Hoisting JS
I’m going through Joel Martin’s amazing teaching tool, mal, which teaches you how to write your own Lisp from scratch. I wanted to get a little better at Javascript, and so chose to use it as my language of implementation.
I’m really glad I’m writing Javascript in the realm of ES6, but there was a bit of hoisting that definitely took me by surprise.
function EVAL(ast, env) {
...
switch (ast[0]) {
case "def!":
[__, first, second] = ast
let value = EVAL(second, env)
...
return value
case "let*":
[__, first, second] = ast
...
return EVAL(second, newEnv)
...
...
It turns out that even with the array destructuring, the variable is hoisted into the global context. I only detected this issue with a def that was nested in a let. In those situations, the variable ‘second’ would be overidden in the nested call, so that it would actually change when it returned to the caller.
If only I had remembered to enable strict mode…