Created
November 8, 2016 14:16
-
-
Save anonymous/d6476b301685c6cb0ce7b523496bf9c1 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
// dynamic scopes | |
// INSTRUCTIONS | |
// - for now, until babel, think of ($)=>{with($){ ... }} as the lambda literal, | |
// '...' is the body and there is nothing else to a lambda | |
// - lambdas don't list argument names, all free variables are bound at callsite | |
// - scopes are constructed with $let({ ... }) and are automatically children | |
// of the surrounding scope | |
// - eval a lambda in a scope with scope.$in(lambda) or lambda(scope) -- thus | |
// both the popular 'before' and 'after' syntax can be used base on use-case | |
// - $ is the current scope, $parent is the parent scope | |
// scopes bootstrap | |
with({ | |
// create a child of current scope with some additions | |
$let(additions = {}) { | |
const child = Object.create(this); | |
Object.assign(child, additions, { | |
$parent: this, | |
}); | |
return child; | |
}, | |
// exprs constructed as ($)=>{with($){ .. }} | |
// $let(x).$in(f) is equivalent to f($let(x)) | |
$in(expr) { | |
return expr(this); | |
}, | |
}){ | |
// 'functions' | |
$let({ | |
// `left` + `right` | |
add: ($)=>{with($){ | |
return left + right; | |
}}, | |
// `left` * `right` | |
mul: ($)=>{with($){ | |
return left * right; | |
}}, | |
// squared length of vector (`x`, `y`) | |
sqLen: ($)=>{with($){ | |
return add($let({ | |
left: mul($let({ left: x, right: x })), | |
right: mul($let({ left: y, right: y })), | |
})); | |
}}, | |
}).$in(($)=>{with($){ | |
// basic `add` | |
console.log( | |
$let({ | |
left: 3, right: 4, | |
}).$in(add) | |
); | |
// ergonomic `add` | |
console.log( | |
add($let({ left: 3, right: 4 })) | |
); | |
// ^ yeah, we can do utils for positional args, coming soon... | |
// missing arg is noticed | |
try { | |
console.log( | |
$let({ | |
left: 4, | |
}).$in(add) | |
); | |
} catch (e) { console.log(e.message); } | |
// basic `sqLen` | |
console.log( | |
$let({ | |
x: 3, y: 4, | |
}).$in(sqLen) | |
); | |
// overriding `mul` in `sqLen` | |
console.log( | |
$let({ | |
mul: ($)=>{with($){ | |
return left / right; | |
}}, | |
x: 3, y: 4, | |
}).$in(sqLen) | |
); | |
// 'objects', 'inheritance' | |
// objects are mainly scopes named explicitly in a scope | |
$let({ | |
Player: $let({ | |
name: 'noname', | |
x: 0, y: 0, | |
far: ($)=>{with($){ return $.$in(sqLen) > 10; }}, | |
}), | |
}).$in(($)=>{with($){ | |
// Player 'class property' | |
console.log( | |
Player.$in(($)=>{with($){ return name; }}) | |
); | |
// Player 'class method' | |
console.log( | |
Player.$in(($)=>{with($){ return sqLen($let()); }}) | |
); | |
console.log( | |
Player.$in(($)=>{with($){ return far($let()); }}) | |
); | |
// Player 'instance' | |
$let({ | |
player: Player.$let({ | |
name: 'thePlayer', | |
x: 20, | |
}), | |
}).$in(($)=>{with($){ | |
console.log( | |
player.$in(($)=>{with($){ return sqLen($let()); }}) | |
); | |
console.log( | |
player.$in(($)=>{with($){ return far($let()); }}) | |
); | |
console.log($); | |
}}); | |
}}); | |
}}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment