digitalmars.D - yield iteration
- anonymous (63/63) Jul 29 2012 A subthread of the "Impressed" thread revolved around D's lack of
- bearophile (22/24) Jul 29 2012 The yield as in Python is so useful and handy, and I miss it
- Tobias Pankrath (1/14) Jul 29 2012 Does this spawn linear many generators?
- bearophile (41/42) Jul 29 2012 I have written this little test code, Python2.6+:
- travert phare.normalesup.org (Christophe Travert) (17/19) Jul 31 2012 I believe most std.algorithm that work on input range could be made to
- travert phare.normalesup.org (Christophe Travert) (2/25) Jul 31 2012
- Timon Gehr (24/24) Jul 29 2012 Ideally it would look like this:
- Timon Gehr (2/26) Jul 29 2012
A subthread of the "Impressed" thread revolved around D's lack of a yield mechanism for iteration. Nick Sabalausky mentioned his earlier attempt to create a library based yield which unfortunately was too slow to compete with explicit opApply/ranges [1]. I took a shot at it. It's fast. The resulting code is reasonably pretty. But it doesn't provide a range interface, just opApply. --- module yielder; import core.thread; /** Examples: --- import yielder; import std.stdio; auto y = new class Yielder!int { final void yielding() { yield(0); yield(13); yield(42); } }; foreach(x; y) { writeln(x); } --- */ class Yielder(E) { abstract void yielding(); this() { this.fiber = new Fiber(&yielding); } private { Fiber fiber; int result; int delegate(ref E) callback; } final int opApply(int delegate(ref E) cb) { callback = cb; result = 0; fiber.reset(); fiber.call(); return result; } final void yield(ref E value) { result = callback(value); if(result != 0) { Fiber.yield(); } } final void yield(E value) { yield(value); } } --- [1] https://semitwist.com/articles/article/view/combine-coroutines-and-input-ranges-for-dead-simple-d-iteration
Jul 29 2012
anonymous:A subthread of the "Impressed" thread revolved around D's lack of a yield mechanism for iteration.The yield as in Python is so useful and handy, and I miss it often in D. This is an example of Inverse Gray iterator (Sloane series A006068) Python2 code from: http://code.activestate.com/recipes/221457/ def A006068(): yield 0 for x in A006068(): if x & 1: yield 2 * x + 1 yield 2 * x else: if x: yield 2 * x yield 2 * x + 1 Turning that in D code that uses opApply is not hard, but the code inflates 3X, and you can't use most std.algorithm on it. I have discussed the situation a little here: http://d.puremagic.com/issues/show_bug.cgi?id=5660 Bye, bearophile
Jul 29 2012
This is an example of Inverse Gray iterator (Sloane series A006068) Python2 code from: http://code.activestate.com/recipes/221457/ def A006068(): yield 0 for x in A006068(): if x & 1: yield 2 * x + 1 yield 2 * x else: if x: yield 2 * x yield 2 * x + 1Does this spawn linear many generators?
Jul 29 2012
Tobias Pankrath:Does this spawn linear many generators?I have written this little test code, Python2.6+: count = 0 def A006068(): global count count += 1 yield 0 for x in A006068(): if x & 1: yield 2 * x + 1 yield 2 * x else: if x: yield 2 * x yield 2 * x + 1 from itertools import islice def main(): global count for p in xrange(15): n = 2 ** p count = 0 print sum(1 for _ in islice(A006068(), 0, n)), count main() The output seems to show that it spawns only logarithmically: 1 1 2 2 4 3 8 4 16 5 32 6 64 7 128 8 256 9 512 10 1024 11 2048 12 4096 13 8192 14 16384 15 Bye, bearophile
Jul 29 2012
"bearophile" , dans le message (digitalmars.D:173647), a écrit :Turning that in D code that uses opApply is not hard, but the code inflates 3X, and you can't use most std.algorithm on it.I believe most std.algorithm that work on input range could be made to work with opApply, or opApply-like delegates. It just wouldn't be particularly efficient unless agressive inlining is used. For example, filter could work like this for opApply-like delegates: template filter(pred) { auto filter(T)(int delegate(int delegate(ref T)) apply) { return (int delegate(ref T) dg) { return apply( (ref T t) { return pred(t)? dg(t): 1; }); } } } -- Christophe
Jul 31 2012
Christophe Travert, dans le message (digitalmars.D:173787), a écrit :"bearophile" , dans le message (digitalmars.D:173647), a écrit :^should read 0Turning that in D code that uses opApply is not hard, but the code inflates 3X, and you can't use most std.algorithm on it.I believe most std.algorithm that work on input range could be made to work with opApply, or opApply-like delegates. It just wouldn't be particularly efficient unless agressive inlining is used. For example, filter could work like this for opApply-like delegates: template filter(pred) { auto filter(T)(int delegate(int delegate(ref T)) apply) { return (int delegate(ref T) dg) { return apply( (ref T t) { return pred(t)? dg(t): 1; });} } } -- Christophe
Jul 31 2012
Ideally it would look like this: struct Map(alias fun, R){ R range; mixin YieldInputRange!q{ for(; !range.empty; range.popFront()) yield fun(range.front); } static if(is(typeof(range.save))) property auto save(){ return Map!(fun, R)(range.save); } ... } Or as a built-in: struct Map(alias fun, R){ R range; yield { for(; !range.empty; range.popFront()) yield fun(x); } static if(is(typeof(range.save))) property auto save(){ return Map!(fun, R)(range.save); } ... }
Jul 29 2012
On 07/29/2012 04:48 PM, Timon Gehr wrote:Ideally it would look like this: struct Map(alias fun, R){ R range; mixin YieldInputRange!q{ for(; !range.empty; range.popFront()) yield fun(range.front); } static if(is(typeof(range.save))) property auto save(){ return Map!(fun, R)(range.save); } ... } Or as a built-in: struct Map(alias fun, R){ R range; yield { for(; !range.empty; range.popFront()) yield fun(x);yield fun(range.front); // oops} static if(is(typeof(range.save))) property auto save(){ return Map!(fun, R)(range.save); } ... }
Jul 29 2012