digitalmars.D - Lazy Literal Range: Stooid late-nite idea?
- Nick Sabalausky (13/13) Oct 08 2011 Suppose you want to search through a range (yea, really hypothetical so
- Vladimir Panteleev (11/14) Oct 08 2011 With the anonymous delegate literal syntax suggested by Andrei a while
- Jacob Carlborg (6/18) Oct 09 2011 Or wrap it in a function taking a list of lazy parameters:
- Lutger Blijdestijn (43/67) Oct 09 2011 typesafe variadics with delegates also allow for this syntax, though not...
- Jacob Carlborg (16/83) Oct 09 2011 Interesting, I didn't know you could do that with a delegate without
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?
Oct 08 2011
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, Vladimir mailto:vladimir thecybershadow.net
Oct 08 2011
On 2011-10-09 08:33, Vladimir Panteleev wrote:On Sun, 09 Oct 2011 06:06:21 +0300, Nick Sabalausky <a a.a> wrote: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 CarlborgGreat, 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.
Oct 09 2011
Jacob Carlborg wrote:On 2011-10-09 08:33, Vladimir Panteleev wrote: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"); }On Sun, 09 Oct 2011 06:06:21 +0300, Nick Sabalausky <a a.a> wrote: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);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.
Oct 09 2011
On 2011-10-09 13:43, Lutger Blijdestijn wrote:Jacob Carlborg wrote: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 CarlborgOn 2011-10-09 08:33, Vladimir Panteleev wrote: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"); }On Sun, 09 Oct 2011 06:06:21 +0300, Nick Sabalausky<a a.a> wrote: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);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.
Oct 09 2011