Skip to content

Instantly share code, notes, and snippets.

Created November 8, 2016 14:16
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 anonymous/d6476b301685c6cb0ce7b523496bf9c1 to your computer and use it in GitHub Desktop.
Save anonymous/d6476b301685c6cb0ce7b523496bf9c1 to your computer and use it in GitHub Desktop.
// 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