Skip to content

Instantly share code, notes, and snippets.

@abuseofnotation
Last active March 25, 2017 16:46
Show Gist options
  • Save abuseofnotation/67dd3729326ef89c384430fce5d2cf66 to your computer and use it in GitHub Desktop.
Save abuseofnotation/67dd3729326ef89c384430fce5d2cf66 to your computer and use it in GitHub Desktop.
/*
* 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