Skip to content

Instantly share code, notes, and snippets.

@clausreinke
Created July 24, 2013 19:59
Show Gist options
  • Save clausreinke/6073990 to your computer and use it in GitHub Desktop.
Save clausreinke/6073990 to your computer and use it in GitHub Desktop.
playing with generators
// node v0.11.4 --harmony
function forof(g,cb) { // non-generator callbacks only
var r;
while(true) {
r = g.next();
if (r.done) break; // skip return value?
cb(r.value);
}
}
function* forofG(g,cb) { // generator callbacks only
var r;
while(true) {
r = g.next();
if (r.done) break; // skip return value?
yield* cb(r.value);
}
}
function log(l,g) {
var i = 0;
console.log(l);
for (var y of g) console.log(i++ + ":",y);
}
function* from(n) { while(true) { yield (n++) } }
function* take(n,g) { for(var y of g) { if (n-->0) { yield y } else { break } } }
// FIXME:
function* take_(n,g) { yield* forofG(g, function*(y) { if (n-->0) { yield y } else { break } }) }
function* map(f,g) { for(var y of g) { yield f(y) } }
function* map_(f,g) { yield* forofG(g, function*(y) { yield f(y) } ) }
function* filter(p,g) { for(var y of g) { if (p(y)) { yield y } } }
function* filter_(p,g) { yield* forofG(g, function*(y) { if (p(y)) { yield y } } ) }
function* zip(g1,g2,cb) {
for (var r1 of g1) {
var r2 = g2.next();
if (r2.done) { break } else { yield cb( r1, r2.value ) }
}
}
function* feed(g1,g2) {
for (var r1 of g1) {
var r2 = g2.next(r1);
if (r2.done) { break } else { yield r2.value }
}
}
function* gen() { (yield 1) ? (yield (yield 2), yield 3) : (yield 4, yield (yield 5)) }
log( "== gen, no feed", gen() );
log( "== take 5 from 0", take_( 5, from(0) ) );
log( "== gen, feed from 0", feed( from(0), gen() ) );
log( "== gen, feed from -1", feed( from(-1), gen() ) );
log( "== take 5 zip", take( 5, zip( from(0), from(1), function(a,b) { return [a,b,a+b] } ) ) );
log( "== take 5 map", take( 5, map_( function(y) { return y*y }, from(1) ) ) );
log( "== take 5 filter", take( 5, filter_( function(y) { return y%2 }, from(1) ) ) );
// function* g1() { yield* (function*(){ yield 1 })() }
// function* g2() { function* y(x){ yield x } yield* y(1) }
// log("-- g1", g1() );
// log("-- g2", g2() );
/* output
== gen, no feed
0: 1
1: 4
2: 5
3: undefined
== take 5 from 0
0: 0
1: 1
2: 2
3: 3
4: 4
== gen, feed from 0
0: 1
1: 2
2: 2
3: 3
== gen, feed from -1
0: 1
1: 4
2: 5
3: 2
== take 5 zip
0: [ 0, 1, 1 ]
1: [ 1, 2, 3 ]
2: [ 2, 3, 5 ]
3: [ 3, 4, 7 ]
4: [ 4, 5, 9 ]
== take 5 map
0: 1
1: 4
2: 9
3: 16
4: 25
== take 5 filter
0: 1
1: 3
2: 5
3: 7
4: 9
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment