On 27 December 2012 21:23, David Herman <dher...@mozilla.com> wrote: > On Dec 27, 2012, at 1:51 AM, Andreas Rossberg <rossb...@google.com> wrote: > > > I think hoisting can mean different things, which kind of makes this > debate a bit confused. > > Yep. Sometimes people mean "the scope extends to a region before the > syntactic position where the declaration appears," sometimes they mean "the > scope extends to the function body," and sometimes they mean "function > declaration bindings are dynamically initialized before the containing > function body or script begins executing." >
Maybe we shouldn't speak of hoisting for anything else but the var case. As I mentioned elsewhere, I rather like to think of it recursive (i.e. letrec-style) block scoping. :) > > There is var-style hoisting. Contrary to what Rick said, I don't think > anybody can seriously defend that as an "excellent" feature. First, because > it hoists over binders, but also second, because it allows access to an > uninitialized variable without causing an error (and this being bad is > where Dave seems to disagree). > > Are you implying that my arguments are not serious? :-( > You are not defending the first part, are you? ;) > > Then there is the other kind of "hoisting" that merely defines what the > lexical scope of a declaration is. The reason we need this > backwards-extended scope is because we do not have an explicit let-rec or > something similar that would allow expressing mutual recursion otherwise -- > as you mention. But it does by no means imply that the uninitialized > binding has to be (or should be) accessible. > > No, it doesn't. I'm not interested in arguments about the "one true way" > of programming languages. I think both designs are perfectly defensible. > All things being equal, I'd prefer to have my bugs caught for me. But in > some design contexts, you might not want to incur the dynamic cost of the > read(/write) barriers -- for example, a Scheme implementation might not be > willing/able to perform the same kinds of optimizations that JS engines do. > In our context, I think the feedback we're getting is that the cost is > either negligible or optimizable, so hopefully that isn't an issue. > Right, from our implementation experience in V8 I'm confident that it isn't in almost any practically relevant case -- although we haven't fully optimised 'let', and consequently, it currently _is_ slower, so admittedly there is no proof yet. But the other issue, which I worry you dismiss too casually, is that of > precedent in the language you're evolving. We aren't designing ES1 in 1995, > we're designing ES6 in 2012 (soon to be 2013, yikes!). People use the > features they have available to them. Even if the vast majority of > read-before-initialization cases are bugs, if there are some cases where > people actually have functioning programs or idioms that will cease to > work, they'll turn on `let`. > > So here's one example: variable declarations at the bottom. I certainly > don't use it, but do others use it? I don't know. > Well, clearly, 'let' differs from 'var' by design, so no matter what, you'll probably always be able to dig up some weird use cases that it does not support. I don't know what to say to that except that if you want 'var' in all its beauty then you know where to find it. :) >> - It binds variables without any rightward drift, unlike functional > programming languages. > > > > I totally don't get that point. Why would a rightward drift be inherent > to declarations in "functional programming languages" (which ones, anyway?). > > Scheme: > > (let ([sq (* x x)]) > (printf "sq: ~a~n" sq) > (let ([y (/ sq 2)]) > (printf "y: ~a~n" y))) > > ML: > > let sq = x * x in > print ("sq: " ^ (toString sq) ^ "\n"); > let y = sq / 2 in > print ("y: " ^ (toString y) ^ "\n") > I don't feel qualified to talk for Scheme, but all Ocaml I've ever seen (SML uses more verbose 'let' syntax anyway) formatted the above as let sq = x * x in > print ("sq: " ^ toString sq ^ "\n"); > let y = sq / 2 in > print ("y: " ^ toString y ^ "\n") Similarly, in Haskell you would write do let sq = x * x > putStr ("sq: " ++ show sq ++ "\n") > let y = sq / 2 > putStr ("y: " ++ show y ++ "\n") > /Andreas
_______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss