lazy thoughts

Denis Koroskin 2korden at gmail.com
Mon Jan 12 14:56:24 PST 2009


On Mon, 12 Jan 2009 20:32:14 +0300, Andrei Alexandrescu <SeeWebsiteForEmail at erdani.org> wrote:

> dsimcha wrote:
>> == Quote from Andrei Alexandrescu (SeeWebsiteForEmail at erdani.org)'s  
>> article
> [snip]
>> I absolutely love it!  Frankly, the convenience of std.algorithm is the  
>> greatest
>> thing since sliced arrays, but all the memory allocation is sometimes  
>> pretty
>> inefficient, so I end up coding lots of stuff at a lower level to avoid  
>> this.  One
>> thing, though, is that I would like to see eager() know whether  
>> whatever it's
>> eager-izing has a predetermined length, and if so, what that  
>> predetermined length
>> is, so it can get by with a single allocation.
>
> Great. Fortunately that will be elegantly supported by the range design:  
> if the range passed to map supports .length, the range returned by map  
> will also support it (and the implementation will simply do the  
> forwarding). Consequently, eager will detect a range that also supports  
> .length, in which case it only does one allocation.
>

Nice, but length might be not known sometimes. How about reducing a restriction of length being either known and fixed or unknown? It could be defined as a "0 if it is the range is empty, minimum number of elements within a range, otherwise". Socket stream is an example of input range that doesn't know length but has a "minimum number of elements left" property.

This way you could check range.length, allocate buffer of enough size, process elements and check range.length once again. Break if it is empty. Continue otherwise:

T[] eager(Generator)(Generator gen)
{
    T[] result;

    while (true)
    {
        int N = range.length;
        if (N == 0) {
            break;
        }

        int lengthSoFar = result.length;
        int newLength = lengthSoFar + N;
        result.length = newLength;
        foreach (i; lengthSoFar..newLength) {
            result[i] = gen();
        }
    }

    return result;
}

> Gotta love static if and is(expression). For years people didn't even  
> know whether or not it's possible to detect (in C++) the existence of a  
> member, let alone the validity of an arbitrary expression. Today  
> detecting the existence of a member is possible but in a very  
> inconvenient and limited manner.
>
>> As far as the confusingness of
>> lazy evaluation, it might take some getting used to, but the really  
>> hard cases
>> could be solved by just using eager() anyhow, and we wouldn't be any  
>> worse off
>> than if lazy weren't supported.
>>  Really, the only downside I see is slightly clumsier syntax when eager  
>> evaluation
>> is needed.  IMHO, this could be improved if eager() were, at least  
>> syntactically,
>> a property of ranges, for example:
>>  map!("a * a")(arr).eager();
>
> How about dropping those parens :o).
>
>
> Andrei

No way!



More information about the Digitalmars-d mailing list