Lazy Literal Range: Stooid late-nite idea?

Jacob Carlborg doob at me.com
Sun Oct 9 08:07:35 PDT 2011


On 2011-10-09 13:43, Lutger Blijdestijn wrote:
> Jacob Carlborg wrote:
>
>> On 2011-10-09 08:33, Vladimir Panteleev wrote:
>>> On Sun, 09 Oct 2011 06:06:21 +0300, Nick Sabalausky<a at a.a>  wrote:
>>>
>>>> Great, right? But what about this?:
>>>>
>>>> auto x = [runtimeExpressionA, runtimeExprB, runtimeExprC,
>>>> etc].find(blah);
>>>
>>> With the anonymous delegate literal syntax suggested by Andrei a while
>>> ago, you should be able to write this as:
>>>
>>> auto x = [() =>  runtimeExpressionA, () =>  runtimeExprB, () =>
>>> runtimeExprC, () =>  etc].find(blah);
>>>
>>> I guess it looks quirky with an empty parameter list, but it's shorter
>>> than writing {return runtimeExpressionA;}, {return runtimeExpressionB;}
>>> etc.
>>>
>>
>> Or wrap it in a function taking a list of lazy parameters:
>> http://www.d-programming-language.org/function.html#parameters
>>
>> auto x = lazyRange(runtimeExpressionA, runtimeExprB, runtimeExprC);
>>
>
> typesafe variadics with delegates also allow for this syntax, though not
> with type inference. I hacked this together:
>
> struct LazyRange(T)
> {
>      import std.array;
>
>      this(T delegate()[] input...)
>      {
>          _input = input;
>      }
>
>      @property
>      bool empty() const
>      {
>          return std.array.empty(_input);
>      }
>
>      void popFront()
>      {
>          std.array.popFront(_input);
>          _isCached = false;
>      }
>
>      @property
>      T front()
>      {
>          if (_isCached)
>              return _front;
>          _front = std.array.front(_input)();
>          _isCached = true;
>          return _front;
>      }
>
> private:
>      T _front;
>      bool _isCached = false;
>      T delegate()[] _input;
> }
>
> unittest
> {
>      import std.algorithm;
>      auto stuff = LazyRange!string("foo",
>                                    "foo" ~ "bar",
>                                    { assert(false); return "bat"; }(),
>                                    "meow");
>      assert(find(stuff,"foobar").front == "foobar");
> }


Interesting, I didn't know you could do that with a delegate without 
declaring a lazy parameter. This works with D1:

void lazyRange (T) (lazy T[] e ...)
{
     foreach (a ; e)
         println(a);
}

void main ()
{
     lazyRange(3, 4);
}

But compiling the same code with D2 results in this error:

Error: escaping reference to local __arrayArg1344

-- 
/Jacob Carlborg


More information about the Digitalmars-d mailing list