Skip to content

Instantly share code, notes, and snippets.

@MaiaVictor MaiaVictor/lambdaSource.js
Last active Oct 19, 2015

Embed
What would you like to do?
Infer the source code of a pure JavaScript function.
// This infers the source code of a pure JavaScript function,
// that is, one consisting of nothing but single-argumented
// lambdas and applications, by applying it to values. Ex:
// lambdaSource(function(x){return x(x)}) == "λx.(x x)"
function lambdaSource(value){
var nextVarId = 0;
return (function normalize(value){
// This is responsible for collecting the argument list of a bound
// variable. For example, in `function(x){return x(a)(b)(c)}`, it
// collects `a`, `b`, `c` as the arguments of `x`. For that, it creates
// a variadic argumented function that is applied to many arguments,
// collecting them in a closure, until it is applied to `null`. When it
// is, it returns the JS source string for the application of the
// collected argument list.
function application(variable, argList){
var app = function(arg){
return arg === null
? argList.length === 0 ? variable : "("+variable+" "+argList.join(" ")+")"
: application(variable, argList.concat(normalize(arg)));
};
app.isApplication = true;
return app;
};
// If we try to normalize an application, we apply
// it to `null` to stop the argument-collecting.
if (value.isApplication)
return value(null);
// If it is a function, we need to create an application for its
// variable, and call the function on it, so its variable can start
// collecting the argList for the places where it is called on the
// body. We then normalize the resulting body and return the JS source
// for the function.
else if (typeof value === "function") {
var varName = "v"+(nextVarId++);
var body = normalize(value(application(varName,[])));
return "λ"+varName+"."+body+"";
} else return value;
})(value);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.