Closed mattbierner closed 10 years ago
Actually the best translation is:
f <\ g;
becomes:
let __f = f, __g = g in f(g(x));
becomes
var f, g;
var __f = f,
__g = g;
(function(x) {
return __f(__g(x));
});
This ensures that both f
and g
are evaluated once and not in the inner function
Slightly better in V0.21.4:
var f:= ..., g := ...;
f \> g;
outputs
"use strict";
var f = (function() {
return 3;
}),
g = (function(x) {
return 2;
}),
x = f,
y = g,
f0 = y,
g0 = x;
(function(x) {
return f0(g0(x));
});
The weird x=f, ...
repeated bindings are caused by a separate issue. The main benefit is that Instead of two inling functions (one inside of the other) for each compose expression, only a function for each compose appears in the code.
However:
f \> g \> f;
Still requires an extra function call for the generated compose code:
"use strict";
var f = (function() {
return 3;
}),
g = (function(x) {
return 2;
}),
x = f,
x0 = g,
y = f,
f0 = y,
g0 = x0,
y0 = (function(x) {
return f0(g0(x));
}),
f1 = y0,
g1 = x;
(function(x) {
return f1(g1(x));
});
Fixed generation of efficient code but not pruning of unreachable funcs:
var f = (+, 10), g = (*, 2) ,z = (_/, 5);
var w = f \> g \> z \>f;
Generates:
var x, x0, x1, y, y0, y1, __divr = (function(x, y) {
return (y / x);
}),
__mul = (function(x, y) {
return (x * y);
}),
__add = (function(x, y) {
return (x + y);
}),
f = (function(y) {
return (10 + y);
}),
g = (function(y) {
return (2 * y);
}),
z = (function(y) {
return (y / 5);
}),
w = ((x = (function(y) {
return (10 + y);
})), (x0 = (function(y) {
return (2 * y);
})), (x1 = (function(y) {
return (y / 5);
})), (y = (function(y0) {
return (10 + y0);
})), (y0 = (function(x2) {
var y1 = x2,
y2 = (y1 / 5);
return (10 + y2);
})), (y1 = (function(x2) {
var y2 = x2,
x3 = (2 * y2),
y3 = x3,
y4 = (y3 / 5);
return (10 + y4);
})), (function(x2) {
var y2 = x2,
x3 = (10 + y2),
y3 = x3,
x4 = (2 * y3),
y4 = x4,
y5 = (y4 / 5);
return (10 + y5);
}));
Which obviously is not very good overall but :
function(x2) {
var y2 = x2,
x3 = (10 + y2),
y3 = x3,
x4 = (2 * y3),
y4 = x4,
y5 = (y4 / 5);
return (10 + y5);
})
is the correct composition.
The problem is that none of the other unreachable bindings are then pruned, #91.
Fixed in V0.21.12
Same input as before:
var f = (+, 10), g = (*, 2) ,z = (_/, 5);
var w = f \> g \> z \>f;
outputs:
use strict";
var __divr = (function(x, y) {
return (y / x);
}),
__mul = (function(x, y) {
return (x * y);
}),
__add = (function(x, y) {
return (x + y);
}),
f = (function(y) {
return (10 + y);
}),
g = (function(y) {
return (2 * y);
}),
z = (function(y) {
return (y / 5);
}),
w = (function(x) {
var x0 = (10 + x),
x1 = (2 * x0),
y = (x1 / 5);
return (10 + y);
});
Current:
Generates
Should be: