Re: Lazy Literal Range: Stooid late-nite idea?
On Sun, 09 Oct 2011 06:06:21 +0300, Nick Sabalausky a@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. -- Best regards, Vladimirmailto:vladi...@thecybershadow.net
Re: Lazy Literal Range: Stooid late-nite idea?
On 2011-10-09 08:33, Vladimir Panteleev wrote: On Sun, 09 Oct 2011 06:06:21 +0300, Nick Sabalausky a@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); -- /Jacob Carlborg
Re: Lazy Literal Range: Stooid late-nite idea?
Jacob Carlborg wrote: On 2011-10-09 08:33, Vladimir Panteleev wrote: On Sun, 09 Oct 2011 06:06:21 +0300, Nick Sabalausky a@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); }
Re: Lazy Literal Range: Stooid late-nite idea?
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 Sabalauskya@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
Lazy Literal Range: Stooid late-nite idea?
Suppose you want to search through a range (yea, really hypothetical so far... ;) ) auto x = [foo, bar, bat, meow].find(bar); assert(x.front == bar); Great, right? But what about this?: auto x = [runtimeExpressionA, runtimeExprB, runtimeExprC, etc].find(blah); Doable, but then *all* those expressions have to be evaluated even if the desired element is one of the first few. What about a range literal, nice and easy like array, but lazily evaluated? I'm not suggesting anything built into the language, of course, just an easily instantiated library type. Good idea? Not hard to make? Already exists? Usefulness likely killed by delegate overhead?