Live data from Hacker News

The Problem with Implicit Scoping in CoffeeScript

lucumr.pocoo.org

101–110 of 137 posts

Re: The Problem with Implicit Scoping in CoffeeScript

#101
post #6

@mitsuhiko Not gonna happen ;) Forbidding shadowing altogether is a huge win, and a huge conceptual simplification. How arrogant! You'd think he'd step back for a second and consider the suggestion, but it sounds like he's on autopilot.

Sorry -- that was supposed to be a friendly tweet-sized response. The discussion about this "feature" is always good to have, especially because it's one of the most rightfully controversial changes that CoffeeScript makes to JavaScript semantics.

There are dozens of lengthy conversations about this in the CoffeeScript issues, if you'd like to take a deeper look.

Re: The Problem with Implicit Scoping in CoffeeScript

#102

Earlier quoted context omitted.

That's a whole different matter, which can't make you shoot yourself in the foot without knowing it for any non-trivial code. CoffeeScript's scoping forces you to always keep track of whatever is enclosing the current scope ALL THE WAY TO THE TOP. This is way too much when your function doesn't need to access outer variables (which should be the minority of the cases). So, problem is, you either make all your functio…

The problem is actually worse. You also have to keep track of all the variables BELOW the current scope as well so you don't accidentally (as in the case of the article) turn a declaration into a reassignment.

yeah that's a sketch thing to have to worry about :s

Re: The Problem with Implicit Scoping in CoffeeScript

#103
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…

ruby is terribly ambiguous..

Re: The Problem with Implicit Scoping in CoffeeScript

#104
post #74
post #55

Earlier quoted context omitted.

Don't jump the gun. The reason is that he's already had many discussions about this and has formed an opinion. See: https://github.com/jashkenas/coffee-script/issues/712 https://github.com/jashkenas/coffee-script/issues/238 Whether he's right is another question. But if you don't like his decision you can use the Coco ( https://github.com/satyr/coco ) fork which fixes it by introducing := for nonlocal assignment.

The reasoning basically seems to be "if you misuse this feature (i.e. have top-level symbols), you'll get bugs (like the OP discovered), therefore don't misuse this feature (i.e. keep your top scopes clean), and therefore you won't get bugs, and therefore it's not a problem with CoffeeScript". It shouldn't take a lot of thought to see why this is a somewhat user-hostile, passive-aggressive approach for a language. If…

I'm afraid that's not quite the reasoning...

Like everything in languages (or APIs), there's a tradeoff here. By making scoping automatic, and (hopefully) forbidding shadowing, you can make the language conceptually simpler. Think of it as making variables be "referentially transparent" in terms of their lexical scope. Everywhere you see "A" within a given lexical scope -- you know that "A" always refers to the same thing. In a language with "var" and with shadowing, "A" could mean many different things within any given lexical scope, and you have to hunt for the nearest declaration to tell which one it is.

On the downside, you have what Armin describes: If you happen to try to use the same name for two different things within the same lexical scope, it won't work.

Since it's always the case that you are able to choose a more descriptive name for your variable, and gain clearer code by it, I think it's very much a tradeoff worth making.

Re: The Problem with Implicit Scoping in CoffeeScript

#105

Earlier quoted context omitted.

In fairness, Armin (the author the blog post) did engage Jeremy (the author of coffeescript) on this issue over twitter. I wish that he would allow comments on his blog. I also wish that he could engage the broader CS community in a proper forum before dissing the language and/or creating a fork of the language. He's overreacting. This whole blog post apparently started because he had a naming collision with "log" in…

> I wish that he would allow comments on his blog. Why? Hackernews and reddit exist and everybody is free to send me a mail or contact me on twitter. This way I do not have to moderate any comments or deal with spam. > I also wish that he could engage the broader CS community in a proper forum before dissing the language and/or creating a fork of the language. And do what? Duplicating an issue that is already there?…

Blog posts about (and against) CoffeeScript features are great, as is discussion on HN, as is discussion on the issues pages.

In addition, nothing in CoffeeScript is set in stone -- because every script compiled with every version of CoffeeScript is compatible with every other version, we're much more comfortable making changes to the language than we otherwise would be. If you can make the case that this change is a good idea, we'll definitely make it. So feel free to comment on the old issue or open a new one if you wish.

Re: The Problem with Implicit Scoping in CoffeeScript

#106
post #77

Earlier quoted context omitted.

Just to be completely clear, variables are only at top level scope if you declare them at top-level scope. The variables "x" below are completely encapsulated within f1 and f2. The variables at top-level scope are intentional in the code below--I really do intend f1, f2, and how_many_times_functions_have_been_called to refer to the same entity throughout the file. how_many_times_functions_have_been_called = 0 f1 = ->…

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 scopes, just within the file you're working in.

Re: The Problem with Implicit Scoping in CoffeeScript

#107

Why not allow CoffeeScript to use the 'var' keyword, explicitly telling CS that this variable should be scoped locally even though it may be shadowing another variable? This seems consistent with their approach of allowing (although optional) native javascript syntax such as {}, and []. This still allows CS to stick to it's paradigm of forbidding shadowing unless we explicitly state that we know what we're doing.

Because we're aiming for a conceptual simplification.

Pretend like you're a beginner, learning this stuff for the first time. If everywhere you see a variable "A", within a certain lexical scope, it means the same thing ... that's much simpler to understand than if "A" means three different things at three different places, because you happened to shadow it twice.

Re: The Problem with Implicit Scoping in CoffeeScript

#108
post #63
post #5

Earlier quoted context omitted.

I agree with this wholeheartedly--Scheme use an extremely simple scoping model that is nonetheless more expressive than Python (before 3, I guess) and CoffeeScript's. In fact, I only really completely understood JavaScript's model--and realized that, even if a little awkward, it was fundamentally elegant--after writing a Scheme interpreter.

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!"

Re: The Problem with Implicit Scoping in CoffeeScript

#109

> The simple solution is to either add a nonlocal keyword like Python has or to introduce a := parameter that works like = but explicitly overrides a higher level variable. I disagree. The simple solution to this is to write tests.

> I disagree. The simple solution to this is to write tests.

That's a step backwards. Code error checking should be done as early as possible. In order of earliness:

* Typing in the code. (Ideal: it is clear from the syntax that the code performs X instead of Y.)

* Compiling. (Strong type checking ensures you cannot return 5.3e7 or null from GetHostName.)

* Running the code at all. (Code contracts and assertions trigger if GetHostName returns "".)

* Automated unit tests. (Check that DB.GetHostName() returns the same string given to DB.Connect().)

* Automated integration tests. (Check that the DB module can connect to and retrieve useful data from a dummy database.)

* QA ("Hey Joe, the system hangs when I give "¤;\@" as my username and press the connect button rapidly for a few seconds.")

* Customer ("Hi the system has a problem, please fix.")

The further up, the faster, more accurately and with less "noise" the error can be discovered.

Re: The Problem with Implicit Scoping in CoffeeScript

#110
post #91

Earlier quoted context omitted.

No, the Javascript model is "you name things with `var`, you mutate things with `=`". Python went for a more complicated scheme of having every variable in a function be a new binding when first assigned, and then it's just mutation (i.e. 'local'), unless explicitly declared to be nonlocal, but it still makes sense with their... penchant for mutable state. And Coffescript instead went over to PHP to have some of the…

No, the Javascript model is "you name things with `var`, you mutate things with `=`". If only it were that simple. It also has "you create thing with `var` and sometimes with `=`", plus it does not have block scope: if( true) { var x = 1; } // x == 1 here.

Functions define scope. The end. Not hard. One rule.
Post reply on HN