jlongster/outlet — Issue #4: let forms can't bind to identical names
Author: jlongster
Created: 2012-02-21 15:31:26+00:00
State: open

Let forms have issues with binding an expression to a variable that has the same name:

(let ((x (+ x 1)))
x) ; returns NaN

This is because the following happens in javascript:

var x = 5;
function () {
var x = x; // undefined
}

Javascript is referencing the variable that is being assigned instead of the outer variable.

`let` compiles to a series of "var = " so that assignment happens sequentially and you can reference preceding vars (similar to Scheme's `letrec`). We could compile it to a function call and this issue goes away, but then vars cannot reference each other.

Outlet fixes the common use case of `(let ((lst lst)) ...)` by ignore that assignment. This doesn't help the issue if the right-hand expression is more complex though, like (car lst).

I think Outlet should gensym all the vars in the list of assignments, because the variable names only matter as the function parameters, which will correctly be what the user specified. So the generated js would look like:

(define x 1)
(let ((x (+ x 1)))
(print x))

var x = 1;
(function() {
function o192(x) {
print(x);
}
var o14 = x + 1;
return o192(o14);
)()