Skip to content

Instantly share code, notes, and snippets.

@rlamacraft
Last active April 10, 2022 15:24
Show Gist options
  • Save rlamacraft/295dd5012ac007d3fe15b84808a37a44 to your computer and use it in GitHub Desktop.
Save rlamacraft/295dd5012ac007d3fe15b84808a37a44 to your computer and use it in GitHub Desktop.
JS without assignment or semicolons; a sort of E-DSL, I guess
/*
* We first need to create a few functions that will facilitate out weird syntax that
* relies on continuation-style programming wherein the next statement is executed as
* a lambda invoked by the previous statement. For clarity, `cf` is shorthand for
* callforward; like a callback, but not really.
*/
const define = (name, body, cf) => scope => cf({...scope, [name]: body(scope)});
const include = (as, module, cf) => scope => cf({...scope, [as]: module});
const main = (body) => scope => body(scope);
const module = (cf) => cf({});
/*
* With those defined, here-on-out we will not use any assignment or semicolons;
* using only continuation-style function calls to sequence instructions.
*/
/*
* Define a module called "BooleanLogic" that exports
* a function "cond", which is basically an if statement.
*/
module(
define("cond",
() => (bool, trueCf, falseCf) =>
bool ? trueCf() : falseCf(),
BooleanLogic =>
/*
* Define a module called "Console" that exports
* a function "log" which wraps the native console.log
*/
module(
define("log",
() => (...x) => console.log(...x),
Console =>
/*
* Define a module of maths functions that exports "lessthan",
* "increment", and "min"
*/
module(
// import the BooleanLogic and Console modules to help
include("BooleanLogic", BooleanLogic,
include("Logging", Console, // we can alias imports: "Console" becomes "Logging"
define("add",
() => (a, b, cf) => cf(a + b),
define("lessthan",
() => (a, b, cf) => cf(a < b),
define("increment",
({add}) => (a, cf) => add(1, a, cf), // this function uses add as previously defined in the new module
define("min",
({BooleanLogic: {cond}, ...maths}) => (a, b, cf) => // this function uses cond from the module BoolLogic and maths.lessthan
maths.lessthan(a, b, (isLt) =>
cond(isLt, () => cf(a), () => cf(b))
),
/*
* A "main" function that computes and logs the minimum of 1 + 1 and 3.
*/
main(
({Logging: {log}, ...maths}) =>
maths.increment(1, x =>
maths.min(x, 3, y =>
log("min(1 + 1, 3) =", y)
))
// Just ignore all these closing parens :P
))))))))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment