On 21.03.2011 19:13, Claus Reinke wrote:
I was looking forward to a Javascript with block scope at last,
but on looking through the proposals, I have some questions:
1. hoisting vs recursive function definitions
Hoisting isn't nice in general,
It's just a technique. It has pros and cons (http://bit.ly/eg4Daz)
and from the "no use before declaration" in [1], it seems that let
bindings won't be hoisted,
not even to their enclosing block.
Why? It does hoisted (at least in the semantics of current SM1.8.5). In
rough approximation, `let` is just a syntactic sugar for immediately
invoked lambdas:
let (x = 10, y = 20) {
/* code */
}
is just a:
(function (x, y) {
/* code */
})(10, 20);
A similarly:
if (true) {
console.log(x, y); // undefined, undefined
let x = 10, y = 20;
console.log(x, y); // 10, 20
}
is just a:
if (true) {
(function () {
console.log(x, y); // undefined, undefined
var x = 10, y = 20;
console.log(x, y); // 10, 20
})();
}
That said, the approximation is rough (after all, things such as
`break`, `continue`, etc. should be considered), but the basic idea is this.
But hoisting is also the basis for making mutually recursive
function definitions work without pain. Will we have to declare
all function names of recursive function groups ahead of defining
them (with a top-down parser, there'd
be many more than just two function names to list)?
{ let odd, even; // needed?
odd = function (n) { .. even(n-1) ..}
even = function (n) { .. odd(n-1) ..}
}
Nope, it seems ugly. If you want a function expression (FE), then use it
as is:
let odd = #(n) {
/* code */
};
Or, since function statements (FS) will be standardized, just:
function odd(n) {
/* code */
}
or, with #functions [2]
{ const odd, even; // needed?
const #odd (n) { .. even(n-1) ..}
const #even (n) { .. odd(n-1) ..}
}
Once function definitions are constant, there doesn't seem
to be much harm in a limited form of hoisting: for a sequence
of constant function definitions, not interrupted by other
statements, implicitly introduce all function names defined in the
sequence at the start of the sequence (to simplify recursive
definitions).
Yes, definitions in loop is also one of the hoisting's reasons (though,
it can be managed an in the system without hoisting).
The alternatives would be manual duplication of function name
lists, or introducing a dedicated letrec syntax for recursive
definitions (the latter might actually be preferable).
Am I missing something here, or hasn't this been discussed?
2. ease of transition
The general idea seems to be to introduce separate syntax,
to force programmers to "buy in" to the new semantics. This
should lead to a clean transition, but not an easy one.
The downside is that no-one can test the waters as long as old
implementations (do not understand 'let') retain substantial
marketshare. This is sad because implementations could
start helping programmers right now (read: from the next
release), to prepare for the eventual transition.
One idea would be to start separating "strong" and "weak"
blocks, where weak blocks '{ }' are the standard, non-scoped
ones and strong blocks '{{ }}' (to steal no syntax) would be
block-scoped (for instance, map to "(function() { }())" ).
Not sure and don't think so. Also, it will complicate the picture in a
whole. Two curly braces are enough for JS from C's syntax.
foo = ->
# coffee
let foo = #() {{
// js
}}
[we can't map '{{ }}' by translating 'var' to 'let': unless all
blocks involved are strong blocks, 'let' is more local]
Another idea would be to add a pragma: "no hoisting";
(or extend "use strict" to encompass this). Upon which
the implementation should warn or error on any code
that captures variable occurences by hoisting. For instance:
function F() {
"no hoisting";
.. x ..
if ( .. ) { var x; .. }
.. x ..
}
Also it seems as a complication for the language. Again, hoisting is
just a technique, there is no need to complicate your code with
additional pragmas (especially with that technically-jargon term
"hoisting"). It's better to build your code accordingly and manually --
just put all definitions to the top yourself.
Dmitry.
should produce warnings (at least at the hoisted declaration,
probably also at the captured uses).
Claus
[1] http://wiki.ecmascript.org/doku.php?id=harmony:let
[2] http://brendaneich.com/2011/01/harmony-of-my-dreams/
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss