Skip to content

Instantly share code, notes, and snippets.

@sebmarkbage
Forked from dherman/cat.js
Last active December 14, 2015 14:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sebmarkbage/5104154 to your computer and use it in GitHub Desktop.
Save sebmarkbage/5104154 to your computer and use it in GitHub Desktop.
// EXAMPLE: a compound iterator with sequencing
// Python style
function cat() {
let is = arguments;
return {
next: {
let length;
while ((length = is.length) > 0) {
try {
return is[length - 1].next();
} catch (e) {
if (isStopIteration(e)) {
is.pop();
continue;
}
throw e;
}
}
throw StopIteration;
}
};
}
// Java style
function cat() {
let is = arguments;
return {
hasNext: function() {
let length = is.length;
return length > 0 && is[length - 1].hasNext();
},
next: function() {
let length;
while ((length = is.length) > 0) {
let i = is[length - 1];
if (!i.hasNext()) {
is.pop();
continue;
}
return i.next();
}
}
};
}
// C# style
function cat() {
// TODO...
}
// Functional style
function cat() {
let is = arguments;
return {
next: function() {
let length;
while ((length = is.length) > 0) {
let next = is[length - 1].next();
if (!next) {
is.pop();
continue;
}
return next;
}
return null;
}
};
}
// Two-callback style
function cat() {
let is = arguments;
return {
next: function(next, done) {
let length;
while ((length = is.length) > 0) {
let next = is[length - 1].next(function(x) {
return { value: x };
}, function() {
return null;
});
if (!next) {
is.pop();
continue;
}
return next.value;
}
return done();
}
};
}
// Node-callback style
function cat() {
let is = arguments;
return {
next: function(cb) {
let length;
while ((length = is.length) > 0) {
let next = is[length - 1].next(function(done, x) {
return done ? null : { value: x };
});
if (!next) {
is.pop();
continue;
}
return next.value;
}
return done();
}
};
}
// StopIteration as return value
function cat() {
let is = arguments;
return {
next: {
let length;
while ((length = is.length) > 0) {
let value = is[length - 1].next();
if (isStopIteration(value)) {
is.pop();
continue;
}
}
return StopIteration;
}
};
}
// EXAMPLE: a leaf iterator
// Python style
function range(low, high) {
let i = low;
return {
next: function() {
if (i >= high)
throw StopIteration;
return i++;
}
};
}
// Java style
function range(low, high) {
let i = low;
return {
hasNext: function() {
return i < high;
},
next: function() {
if (i >= high)
throw new Error("no next");
return i++;
}
};
}
// C# style
function range(low, high) {
let i = low - 1;
return {
get current() {
if (i < low)
throw new Error("not started");
if (i >= high)
throw new Error("finished");
return i;
},
moveNext: function() {
i++;
return i < high;
}
};
}
// Functional style
function range(low, high) {
let i = low;
return {
next: function() {
return i >= high ? null : { value: i++ };
}
};
}
// Two-callback style
function range(low, high) {
let i = low;
return {
next: function(next, done) {
return i >= high ? done() : next(i++);
}
};
}
// Node-callback style
function range(low, high) {
let i = low;
return {
next: function(cb) {
return i >= high ? cb(true) : cb(false, i++);
}
};
}
// StopIteration as return value
function range(low, high) {
let i = low;
return {
next: function() {
if (i >= high)
return StopIteration;
return i++;
}
};
}
// EXAMPLE: a compound iterator
// Python style
function zip(i1, i2) {
return {
next: function() {
return [x1.next(), x2.next()];
}
};
}
// Java style
function zip(i1, i2) {
return {
hasNext: function() {
return x1.hasNext() && x2.hasNext();
},
next: function() {
return [x1.next(), x2.next()];
}
};
}
// C# style
function zip(i1, i2) {
return {
get current() {
return [i1.current, i2.current];
},
moveNext: function() {
return i1.moveNext() && i2.moveNext();
}
};
}
// Functional style
function zip(i1, i2) {
return {
next: function() {
let x1 = i1.next();
if (!x1)
return null;
let x2 = i2.next();
if (!x2)
return null;
return { value: [x1, x2] };
}
}
}
// Two-callback style
function zip(i1, i2) {
return {
next: function(next, done) {
return i1.next(function(x1) {
return i2.next(function(x2) {
return [x1, x2];
}, done);
}, done);
}
};
}
// Node-callback style
function zip(i1, i2) {
return {
next: function(cb) {
return i1.next(function(done, x1) {
if (done) {
return cb(true);
}
return i2.next(function(done, x2) {
if (done) {
return cb(true);
}
return cb(false, [x1, x2]);
});
});
}
};
}
// StopIteration as return value
function zip(i1, i2) {
return {
next: function() {
let tuple = [i1.next(), i2.next()];
if (isStopIteration(tuple[0]) || isStopIteration(tuple[1])) {
return StopIteration;
}
return tuple;
}
};
}
// EXAMPLE: a compound iterator that checks for end of iteration
// Python style
function zipExtend(i1, i2, extendWith) {
function next(i, ifDone) {
try {
return i.next();
} catch (e) {
if (isStopIteration(e)) {
ifDone();
return extendWith;
}
throw e;
}
}
return {
next: function() {
let x1 = done1 ? extendWith : next(i1, function() {
done1 = true;
});
let x2 = done2 ? extendWith : next(i2, function() {
done2 = true;
});
if (done1 && done2)
throw StopIteration;
return [x1, x2];
}
};
}
// Java style
function zipExtend(i1, i2, extendWith) {
return {
hasNext: function() {
return i1.hasNext() || i2.hasNext();
},
next: function() {
if (!i1.hasNext() && !i2.hasNext())
throw new Error("end of iterator");
return [i1.hasNext() ? i1.next() : extendWith,
i2.hasNext() ? i2.next() : extendWith];
}
};
}
// C# style
function zipExtend(i1, i2, extendWith) {
// TODO
}
// Functional style
function zipExtend(i1, i2, extendWith) {
return {
next: function() {
var x1 = i1.next(), x2 = i2.next();
return (!x1 && !x2) ? null : {
value: [x1 ? x1.value : extendWith,
x2 ? x2.value : extendWith]
};
}
};
}
// Two-callback style
function zipExtend(i1, i2, extendWith) {
return {
next: function(next, done) {
return i1.next(function(x1) {
return i2.next(function(x2) {
return next([x1, x2]);
}, function() {
return next([x1, extendWith]);
});
}, function() {
return i2.next(function(x2) {
return next([extendWith, x2]);
}, done);
});
}
};
}
// Node-callback style
function zipExtend(i1, i2, extendWith) {
return {
next: function(cb) {
return i1.next(function(done, x1) {
return done
? i2.next(function(done, x2) {
return done ? cb(true) : cb(false, [extendWith, x2]);
})
: i2.next(function(done, x2) {
return cb(false, [x1, done ? extendWith : x2]);
});
});
}
};
}
// StopIteration as return value
function zipExtend(i1, i2, extendWith) {
return {
next: function() {
let v1 = i1.next(), v2 = i2.next();
if (isStopIteration(v1) && isStopIteration(v2)) {
return StopIteration;
}
return [isStopIteration(v1) ? extendWith : v1,
isStopIteration(v2) ? extendWith : v2];
}
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment