April 23, 2020
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?
April 23, 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?

Nevermind. Got it!

I wonder if phobos generic code should even account for that 🤔


April 23, 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?


1 2 3
Next ›   Last »