A handful of useful macros as babel-plugin.
npm install --save-dev babel-plugin-transform-js-macros
.babelrc
<- { "plugins": ["babel-plugin-transform-js-macros"] }
Detect free variables in an expression and return a lambda that takes those as arguments.
(symbolic, x + y);
gives
({ x, y }) => x + y;
Mimics haskell do-notation. Takes an additional function to flatten the structure.
(join,
x = 1,
y = 2,
3
);
gives
_joiner => _joiner(1, x => _joiner(2, y => 3));
examples:
// Promise chain
const then = (promise, callback) => Promise.resolve(promise).then(callback);
const six = (join,
x = Promise.resolve(4), // binding a Promise
y = x * 2, // Promise.resolve will take care non-promise values
Promise.resolve(y - 2)
);
six(then).then(console.log); // 6
// Maybe
class Nothing {
mbind(f) {
return new Nothing();
}
}
class Just {
constructor(x) {
this.x = x;
}
mbind(f) {
return f(this.x);
}
}
const bind = (monad, binder) => monad.mbind(binder);
// here the magic
const plus3 = n => (join,
a = n, // n must be a monad
b = new Just(3),
new Just(a + b)
)(bind);
expect(plus3(new Nothing())).toEqual(new Nothing());
expect(plus3(new Just(5))).toEqual(new Just(8));
const toArray = (item, next) => [item].concat(next(item));
expect((join,
a = 1,
b = 2,
a + b
)(toArray)).toEqual([1, 2, 3]);
const assign = (item, next) => next(item);
expect((join,
a = 1,
b = 2,
{ a, b }
)(assign)).toEqual({ a: 1, b: 2 });
- fix name collision
- allow nested macros