Skip to content

Instantly share code, notes, and snippets.

View awto's full-sized avatar

Vitalii Akimov awto

View GitHub Profile
@awto
awto / tdpe.js
Last active September 3, 2019 04:14
Normalization by evaluation in JavaScript
const AbstractSym = Symbol("Abstract");
function abstract(init) {
const proxy = new Proxy(
function() {
throw new Error("shouldn't be called");
},
{
get(object, prop) {
if (prop === AbstractSym) return init;
@awto
awto / AST_transform_using_generators.md
Last active May 26, 2019 14:48
Using Generators instead of Visitors simplifies compiler's development

AST transform using Generators

This transformation technique is used in @effectful/js and I use the same for other compilers (not based on babel though).

As the first step, this splits AST into a stream of tokens (simle ECMAScript Iterator), and as the last step, it builds the node back from the argument Iterator. There are a few functions for transforming the streams in the middle (stream transducers). They take an Iterable object and return some other (transformed) Iteratable. In most cases, the transformer function (transducer) is a Generator.

This way, transformations composition is just a plain function's composition. E.g. node => consume(transform1(transform2(produce(node)))) or with any pipe function/operator. And it is just a single pass. All transforms run simultaneously passing the transformed tokens to the next one.

Motivation

@awto
awto / join.js
Created March 8, 2019 15:13
Join Async
async function join(input) {
const output = [];
for(const i of input)
output.push(await i);
return [...output];
}
@awto
awto / join.js
Created March 8, 2019 15:08
join from chain and of
const join = (of, chain) => args => args.reduceRight(
(acc, eff) => result => chain(eff, element => acc([...result, element])), of)([]);
@awto
awto / useState.js
Last active March 8, 2019 14:50
continuation monad with suspense
const runCont = run(
value => cont => cont(value),
(arg, next) => cont => arg(value => next(value)(cont)));
const useState = initial =>
M(cont =>
cont([initial, function next(value) { cont([value,next]); }]));
@awto
awto / promise.js
Last active March 8, 2019 14:40
Run Promise
const runPromise = run(
v => Promise.resolve(v),
(arg, f) => arg.then(f));
@awto
awto / suspense.js
Last active March 9, 2019 14:38
Abstract Suspense
/** effectful expression throws this object if it requires suspension */
const token = {};
/** Pointer to mutable data used to record effectful computations */
let context;
/** Runs `thunk()` as an effectful expression with `of` and `chain` as Monad's definition */
const run = (of, chain) => thunk => {
/** here it caches effects requests */
const trace = [];
@awto
awto / effects.js
Last active July 11, 2019 07:17
Single syntax layer effects using exceptions - React Hooks style
class Token { constructor(v) { this.value = v, this.results = [] } }
let context
const run = (of, chain) => (fun) => (...args) => {
const trace = []
const ctx = {trace}
return walk()
function walk(bound) {
const savedContext = context
@awto
awto / non-det.js
Last active June 14, 2018 08:31
non-determinism
const nonDet = run(
function*(value) { yield value },
function*(arg, fun) {
for(const i of arg)
yield* fun(i)
})
@awto
awto / promise.js
Last active June 12, 2018 05:46
abstract promise
const promise = run(v => Promise.resolve(v),
(arg, fun) => arg.then(fun))