Discussion Thread: DIP 1033--Implicit Conversion of Expressions to Delegates--Community Review Round 1

Meta jared771 at gmail.com
Thu Apr 23 22:32:00 UTC 2020


On Thursday, 23 April 2020 at 20:15:19 UTC, aliak wrote:
> On Thursday, 23 April 2020 at 14:49:53 UTC, Meta wrote:
>> On Thursday, 23 April 2020 at 13:20:08 UTC, Guillaume Piolat 
>> wrote:
>>> On Thursday, 23 April 2020 at 11:13:34 UTC, Patrick Schluter 
>>> wrote:
>>>>
>>>> I always thought that lazy should also be marked at the call 
>>>> site as it is a very different semantic on the caller and on 
>>>> the callee. As it is now, it is true that the example above 
>>>> is unfortunate and a real source of unpleasant surprizes.
>>> +1
>>>
>>> Step 1: lazy must be used at the call site
>>
>> That would play havoc with generic code and would 
>> significantly increase the complexity of standard phobos 
>> functions like map, filter, etc.
>
> Can you elaborate? How so?

This is not how those functions are implemented, but it should 
illustrate my point:

auto function map(alias fun)(Range!T range)
{
     T[] result;
     foreach (i, item; range)
         result[i] = fun(item);

     return result;
}

int evenicize(lazy int n)
{
     if (n % 2 == 1)
         return n * 2;
}

auto odds = [1, 3, 5, 7];

//If the call site needs an explicit "lazy" for arguments to lazy 
parameters:
auto evens = odds.map!evenicize(); //Error: must specify "lazy" 
for parameter n when calling function "evenicize"

So then map has to account add a bunch of extra machinery to 
detect whether "fun" has any lazy parameters:

template hasLazyParameter(alias fun)
{
     //Some implementation
}

auto function map(alias fun)(Range!T range)
{
     //Note, if you had to write this as "fun(lazy T.init)", 
typeof would fail here
     typeof(fun(T.init))[] result;
     foreach (i, item; range)
         static if (hasLazyParameter!fun)
             result[i] = fun(lazy item);
         else
             result[i] = fun(item);

     return result;
}

Which actually is not that bad for map, as the function you pass 
to it only takes 1 parameter (although IMO, this is already too 
onerous).

But what about something like std.functional.reverseArgs, which 
has to be able to handle functions with arbitrary arity?




More information about the Digitalmars-d mailing list