On 27 December 2012 21:23, David Herman <[email protected]> wrote:
> On Dec 27, 2012, at 1:51 AM, Andreas Rossberg <[email protected]> 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
[email protected]
https://mail.mozilla.org/listinfo/es-discuss