Live data from Hacker News

The Problem with Implicit Scoping in CoffeeScript

lucumr.pocoo.org

111–120 of 137 posts

Re: The Problem with Implicit Scoping in CoffeeScript

#111

Earlier quoted context omitted.

Mootools still disqualifies itself in my mind by patching around on builtins.

certainly, but that's besides the point. If you look at the jQuery community vs the others, jQuery's is filled with much much more spaghetti code

jQuery makes the DOM so dang accessible that people use it as their data, which is completely backwards. Fortunately stuff like backbone has brought back some sanity.

Re: The Problem with Implicit Scoping in CoffeeScript

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

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
      ... more code here ...
        someVariable
          ... more code here ...
            someVariable
          ... more code here ...
        someVariable
... in the above code, you can know that "someVariable" always refers to the same thing. 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.

If you really want three different values, use three different names. In all cases, it will read better than shadowing would have.

Re: The Problem with Implicit Scoping in CoffeeScript

#113

Earlier quoted context omitted.

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

> 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.

This attitude concerns me. I can't just say "oh, that's CoffeeScript 1.0 stuff, just trash it, the JS still works". I still have to update the CoffeeScript to upgrade the version. There's no less risk in breaking backwards compat with CoffeeScript than any other language.

Re: The Problem with Implicit Scoping in CoffeeScript

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

If you really favor protection from errors, then the correct choice is to require 'var' for new declarations but forbid shadowing (it's an error). Shadowing a la Scheme is a source of errors, too -- you can intend the outer variable, failing to notice it's been shadowed. Of course, if you really favor early detection of errors, you'll also have static name binding.

Re: The Problem with Implicit Scoping in CoffeeScript

#115

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.

Yea, I completely get what you're saying and for the most part agree. To be frank, I think the author of the article made an error in deconstructing on the 'Math' object (at least at a global scope). 'Math' provides a namespace for all of its methods and a similar approach should be taken to other libraries/pieces of code. I also agree that keeping things simple and straight forward makes sense, but you're doing it by forcing one to abide by those standards although someone might have completely legitimate reasons for explicitly scoping their variables.

Either way, I think it is what it is and the benefits of CS very much outweigh the cons. Thanks for the feedback

Re: The Problem with Implicit Scoping in CoffeeScript

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

The problem with mandatory conventions is that they represent a different kind of user hostility--you're not trusting the developer to make his own decisions about variable names.

To give an example, many CoffeeScript programmers do follow simple naming conventions to call out top-level variables, such as CamelCase for classes or ALL_CAPS for constants. When you follow these conventions, it's pretty easy to avoid naming collisions.

In certain cases, though, you want a top-level variable to be lowercase, perhaps for stylistic reasons. If your files are relatively small, it's pretty easy to check for naming collisions when you introduce top-level variables after the fact, so a developer might decide that the risk is acceptable, especially if there is good test coverage.

Another kind of user hostility is to optimize for safety at all costs. I don't think any scoping mechanism totally eliminates the possibility of bugs, but some schemes do err on the side of safety over convenience. There's nothing wrong with trading off convenience for safety, but, on the other hand, you can make judgment calls that convenience and/or simplicity of the scoping model outweigh the risk of naming collisions.

Obviously, I like CoffeeScript, so I think Jeremy's made the correct tradeoffs. All languages work a little different--JavaScript, CoffeeScript, Python2, Python3, and Ruby all have different rules--and none of them are perfect in all situations. In all of the languages, though, it's reasonably straightforward to write correct code once you adopt general good practices--be careful with your names, and understand the language's approach to scoping.

Re: The Problem with Implicit Scoping in CoffeeScript

#117
post #74

Earlier quoted context omitted.

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…

You haven't said anything new to me here; I took all this for granted and it isn't what I'm criticizing. You haven't actually addressed my summary of the apparent reasoning for why accidental assignments to top-level symbols isn't a pathology of CoffeeScript. The bit I'm criticizing is the failure mode of "if you happen to try to use the same name for two different things within the same lexical scope, it won't work".

Re: The Problem with Implicit Scoping in CoffeeScript

#118
post #36

FWIW this is how CS works: top_level_variable = null f = -> top_level_variable = "hello" f() console.log top_level_variable # prints hello

The concern is that because Coffeescript automatically scopes variables to the scope of their first reference, it can introduce maintenance issues. Consider the following: foo = -> bar = "woot!" console.log bar This compiles to: var foo; foo = function() { var bar; bar = "woot!"; return console.log(bar); }; bar is locally scoped to foo(). Now, 2 weeks later and 200 lines earlier, you come along and define: bar = -> a…

There is some discussion here on why a "bar" variable at top level only affects the scoping of other "bar" variables that are lexically below "bar" in the file, not above it.

https://github.com/jashkenas/coffee-script/issues/1121

Re: The Problem with Implicit Scoping in CoffeeScript

#119
post #84
post #83

Earlier quoted context omitted.

That makes plenty of sense to me; when do you ever want to leak a for loop counter to an outer scope?

And when do you ever want to leak local variables to an outer scope? Never. Not to mention that loop counters are no different than other `var`iables in JS.

You do want to sometimes reference outer scope variables from inner scopes, though. The only difference between a leaked local and a properly referenced global is usage semantics.

Re: The Problem with Implicit Scoping in CoffeeScript

#120

Earlier quoted context omitted.

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…

You haven't said anything new to me here; I took all this for granted and it isn't what I'm criticizing. You haven't actually addressed my summary of the apparent reasoning for why accidental assignments to top-level symbols isn't a pathology of CoffeeScript. The bit I'm criticizing is the failure mode of "if you happen to try to use the same name for two different things within the same lexical scope, it won't work"…

I see. The reason I can't address your "failure mode" with an explicit suggestion is because it isn't a failure mode in CoffeeScript: If you assign a new value to a variable in an inner scope, the variable now has a new value. If you're thinking "I want to use the same name for two different variables" ... the answer is: choose a different (better) name for one of them.

But perhaps I'm still not getting at the answer you're looking for here...

Post reply on HN