Skip to content

Instantly share code, notes, and snippets.

@anler
Last active April 29, 2016 15:26
Show Gist options
  • Save anler/3b42b313a372fcb1a60acb1cd61a78db to your computer and use it in GitHub Desktop.
Save anler/3b42b313a372fcb1a60acb1cd61a78db to your computer and use it in GitHub Desktop.
Purely functional implementation of streams in JavaScript borrowed from SICP
const EMPTY = null;
console.clear();
var naturals$ = Naturals()
var firstFive$ = take(5, naturals$)
applyEach(
n => console.log(n),
firstFive$
)
// 1 2 3 4 5
function Naturals(startAt=1) {
return unshift(
startAt,
defer(Naturals, startAt + 1)
)
}
function take(n, s) {
if (isEmpty(s) ||
n < 1) return empty()
return unshift(
head(s),
defer(take, n - 1, tail(s))
)
}
function defer(f, ...args) {
return function() {
return f.apply(null, args)
}
}
function applyEach(f, s) {
if (isEmpty(s)) return empty()
f( head(s) ) // side-effect
return applyEach(
f,
tail(s)
)
}
function head(s) {
return s('head')
}
function tail(s) {
return demand( s('tail') )
}
function demand(f) {
return f();
}
function unshift(head, tail) {
return function get(ref) {
switch (ref) {
case 'head': return head;
case 'tail': return tail;
}
}
}
function empty() {
return EMPTY;
}
function isEmpty(s) {
return s === EMPTY;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment