curry and partially apply functions or macros with sweet.js
/*output*//*
var foo = 'd', bar = 'e';
console.log('a', 'b', 'c', foo, bar);
console.log('a', 'b', 'c', foo, 2, 3, 4, 5);
console.log('a', 'c', 'b');
console.log('a', 'd', 'b', 'f', 'e', 'g', foo);
function veryLongFunction() {
console.log.apply(console, arguments);
}
veryLongFunction('a', 'b', 'c', 'd', 'e', 'f');
veryLongFunction('a', 'b', 'c', foo, bar, 'baz');
*/
macro curried {
rule { $($id = $mac($opt (,) ...)) (,) ... ; } => {
$(let $id = macro {
rule { ($rest (,) $[...]) } => {
$mac($opt (,) ..., $rest (,) $[...])
}
rule { } => { $id }
}) ...
}
}
macro partial {
rule { $($id = $mac($opts (,) ...)) (,) ... ; } => {
$(let $id = macro {
case {_ ($rest (,) $[...]) } => {
var args = [], opts = #{ $opts ... }, rest = #{ $rest $[...] },
i = -1, n = opts.length,
j = -1, k = -1;
while(++i < n) {
var opt = opts[i],
tok = opt.token,
val = tok && tok.value;
args[++j] = val === "_" &&
tok.type === parser.Token.Identifier ?
rest[++k] : opt;
}
n = rest.length;
while(++k < n) { args[++j] = rest[k]; }
letstx $args $[...] = args;
return #{ $mac($args (,) $[...]) }
}
}) ...
}
}
macro veryLongArgsList {
rule { ($args (,) ...) ; } => {
console.log($args (,) ...) ;
}
}
var foo = "d", bar = "e";
curried curriedMacro = veryLongArgsList("a", "b", "c"),
curriedAgain = curriedMacro(foo);
curriedMacro(foo, bar);
curriedAgain(2, 3, 4, 5);
partial partialMacro = veryLongArgsList("a", _, "b"),
partialAgain = partialMacro("d", _, "e");
partialMacro("c");
partialAgain("f", "g", foo);
function veryLongFunction() {
console.log.apply(console, arguments);
}
curried curriedFunc = veryLongFunction("a", "b", "c"),
curriedFuncAgain = curriedFunc(foo);
curriedFunc("d", "e", "f");
curriedFuncAgain(bar, "baz");