Last active
October 19, 2015 16:58
-
-
Save VictorTaelin/1f0afbdb0ef173620c95 to your computer and use it in GitHub Desktop.
Infer the source code of a pure JavaScript function.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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