Live data from Hacker News

The Problem with Implicit Scoping in CoffeeScript

lucumr.pocoo.org

131–137 of 137 posts

Re: The Problem with Implicit Scoping in CoffeeScript

#131

Earlier quoted context omitted.

I think you think you're being sarcastic. But I do actually work for a developer tools company, and I implement language features on a continuous basis. I implemented anonymous methods - closures - for Delphi, a task that involves no small amount of scope wrangling; and FWIW, Delphi almost certainly has a larger userbase than CoffeeScript, albeit one with greyer hairs. While my specialism is in statically typed, comp…

Ok, I'll dial back the snark and just be blunt. I think all your concerns about CoffeeScript are hypothetical exaggerations. I don't think you've written much CoffeeScript at all, and I suspect that if you did, you'd quickly see that your concerns are overblown. In theory, you could have thousands of lines in a single file, and two commits from a separate branch could cause an undetectable accidental naming collision…

I think if you have good practices - small files, scrutiny of changes, unit tests - you can make any language work. The test of a language comes in how it bites you when you stray. So to be blunt, I think your defense is irrelevant.

Re: The Problem with Implicit Scoping in CoffeeScript

#132
post #63

Earlier quoted context omitted.

I think Python's is deliberately unexpressive, forcing you to use local variables pretty much everywhere. This tends to decouple stuff, which is usually good. The model is "everything you do is local, unless you know better, and want to jump through a lot of hoops". Coffeescript works a similar way. Javascript seems to have the model "everything you do is global, unless you know better". I'm not a big Javascript hate…

'let' is a way to make things more local! When I say: let x = 0, I'm saying "hey, I don't care what 'x' is in other scopes, in this local scope it's 10, dammit!"

Yes explicit is best and in Perl its very clear what you want...

  my $x = 10;

Re: The Problem with Implicit Scoping in CoffeeScript

#133
post #52

It's worth pointing out that JavaScript 1.7 resolves this mess by introducing block scoping using the "let" keyword. It works just like it does in Scheme, Common Lisp, and Clojure (i.e., correctly). Not supported in anything except Firefox, unfortunately.

... and Standard ML, OCaml, Haskell, Smalltalk, etc

... and Perl except its called my instead of let

Re: The Problem with Implicit Scoping in CoffeeScript

#134
post #90

I'll copy below jashkenas' longer answer from the old github issue about this, https://github.com/jashkenas/coffee-script/issues/712#issuec... """ Sorry, folks, but I'm afraid I disagree completely with this line of reasoning -- let me explain why: Making assignment and declaration two different "things" is a huge mistake. It leads to the unexpected global problem in JavaScript, makes your code more verbose, is a hug…

[Shadowing] prevents you from making use of the original value for the remainder of the current scope.

That's totally false.

In languages like Scheme, O'Caml, etc you are never prevented from using the original value.

The point is that lexical, aka static scope is all about lexical pieces of code that you fully control, and all their properties are statically apparent, by looking at a single piece of code.

Scheme:

  (DEFINE FOO 1)
  (LET ((FOO 2)) ... FOO IS SHADOWED HERE ...)
Inside the LET, FOO is shadowed (FOO is "your FOO") and that's lexically, statically apparent by looking at the piece of code.

If you don't want it shadowed, and use the global FOO, you just use another variable name. You cannot be prevented from using the original global FOO, because you choose the local variable names you use in a piece of code.

Re: The Problem with Implicit Scoping in CoffeeScript

#135

Earlier quoted context omitted.

and well-factored code has very few variables in the top-level scope -- and they're all things like namespaces and class names Unless you happen to embrace JavaScript's functional side and write lots of top level helper functions (in a closure of course after which you export) shadowing the variable is the wrong answer. It completely prevents you from making use of the original value for the remainder of the current…

I may just ask you in a few minutes when you get in ... but what exactly is the scoping scheme (and generated JavaScript) that you're proposing here, without "var", "nonlocal", ":=", and with shadowing? In addition, to repeat myself elsewhere in this thread, the goals here are conceptual simplification and readability, not giving the programmer more control over scope. The final result is that hopefully: someVariable…

In all cases, it will read better than shadowing would have.

You are going against the consensus established by ALGOL and Scheme (and used by most languages in the functional camp since then) here. That's your prerogative of course, but personally I'd be wary of design choices that go against established wisdom.

With "var", the above code could allow "someVariable" to refer to three different things, each for slightly different sections of the above chunk of code.

Yes, but that's not an issue, as it is easy to check (by looking at the code section in isolation) which of the three bindings an identifier refers to - which is, for me, the definition of lexical, static scope.

Re: The Problem with Implicit Scoping in CoffeeScript

#136
post #134
post #90

I'll copy below jashkenas' longer answer from the old github issue about this, https://github.com/jashkenas/coffee-script/issues/712#issuec... """ Sorry, folks, but I'm afraid I disagree completely with this line of reasoning -- let me explain why: Making assignment and declaration two different "things" is a huge mistake. It leads to the unexpected global problem in JavaScript, makes your code more verbose, is a hug…

[Shadowing] prevents you from making use of the original value for the remainder of the current scope. That's totally false. In languages like Scheme, O'Caml, etc you are never prevented from using the original value. The point is that lexical, aka static scope is all about lexical pieces of code that you fully control , and all their properties are statically apparent, by looking at a single piece of code. Scheme: (…

You cannot be prevented from using the original global FOO, because you choose the local variable names you use in a piece of code.

Unless you're using a system in which non-hygienic macros are present and they expand into it...

Re: The Problem with Implicit Scoping in CoffeeScript

#137
post #77

Earlier quoted context omitted.

Yes, I probably wasn't very clear: what I meant is that a programmer writing a function somewhere in a program must have a complete knowledge of the scope where the function is and will be in the future, including changes in global variables exposed by the interpreter/browser. In the end I would find me forced to add a prefix to all the variables in order to avoid collisions, just like I would be forced to do, if the…

Fortunately, what you're describing isn't how it works. CoffeeScript will automatically declare all variables in the nearest lexical scope it can find. The top-level scope in CoffeeScript isn't global -- it's the top of the file. You don't have to know anything about what values may or may not exist in global scope at any given moment ... all you have to know is what variables are visible in your function's enclosing…

Oh, I see. And you fiddle with globals by manipulating the window/exports object, which I assume are reserved identifiers.

Thanks a lot for clarifying that, it doesn't look that bad this way.

Post reply on HN