Last active
March 25, 2017 16:46
-
-
Save abuseofnotation/67dd3729326ef89c384430fce5d2cf66 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Implementation | |
*/ | |
// Takes an object containing several effectful functions, | |
// Returns a similar object where function does not do IO, but just returns an object with its name and args. | |
const constructDsl = (obj) => Object.keys(obj).reduce((valueObj, fn) => { | |
valueObj[fn] = (...args) =>({fn, args}) | |
return valueObj | |
}, {}) | |
// Takes a "main" function and an IO object. | |
// Calls the main function with a DSL object supporting the functions provided by the IO object | |
const exec = (main, ioObject) => { | |
// Does not support async stuff, but it can be refactored easily | |
let computation = main(constructDsl(ioObject)) | |
instance = computation.next() | |
while (!instance.done) { | |
const valueInterpreted = ioObject[instance.value.fn](...instance.value.args) | |
// Uncomment this to log the result of every effectful computation that is done in the program: | |
// console.log('---Computation finished with result', valueInterpreted) | |
instance = computation.next(valueInterpreted) | |
} | |
} | |
/* | |
* Usage | |
*/ | |
// 1. Define all impure functions that your program uses: | |
const ioObject = { | |
get(key) { | |
const store = { | |
a: 1, | |
b: 2, | |
c: 3 | |
} | |
return store[key] | |
}, | |
set(key, val) { | |
store[key] = val | |
}, | |
log(val) { | |
console.log(val) | |
} | |
} | |
// 2. Define your program. Call the functions as you normally would but with 'yield'. | |
function* main (io){ | |
yield io.log( yield io.get('c')) | |
yield io.log('Done') | |
} | |
// 3. Execute your program with your interpreter | |
exec(main, ioObject) //Prints "3" and "Done" | |
// 4. Execute your program with a different interpreter | |
const browserIoObject = { | |
get(key) { | |
return window.localStorage.getItem(key) | |
}, | |
set(key, val) { | |
return window.localStorage.setItem(key, val) | |
}, | |
log(val) { | |
console.log(val) | |
} | |
} | |
//exec(main, browserIoObject) // Only run in browser |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment