TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

The Problem with Implicit Scoping in CoffeeScript

133 点作者 michaelty超过 13 年前

17 条评论

mhansen超过 13 年前
I'll copy below jashkenas' longer answer from the old github issue about this, <a href="https://github.com/jashkenas/coffee-script/issues/712#issuecomment-430673" rel="nofollow">https://github.com/jashkenas/coffee-script/issues/712#issuec...</a><p>"""<p>Sorry, folks, but I'm afraid I disagree completely with this line of reasoning -- let me explain why:<p>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 huge source of confusion for beginners who don't understand well what the difference is, and is completely unnecessary in a language. As an existence proof, Ruby gets along just fine without it.<p>However, if you're not used to having a language without declarations, it seems scary, for the reasons outlined above: "what if someone uses my variable at the top of the file?". In reality, it's not a problem. Only the local variables in the current file can possibly be in scope, and well-factored code has very few variables in the top-level scope -- and they're all things like namespaces and class names, nothing that risks a clash.<p>And if they do clash, shadowing the variable is the wrong answer. It completely prevents you from making use of the original value for the remainder of the current scope. Shadowing doesn't fit well in languages with closures-by-default ... if you've closed over that variable, then you should always be able to refer to it.<p>The real solution to this is to keep your top-level scopes clean, and be aware of what's in your lexical scope. If you're creating a variable that's actually a different thing, you should give it a different name.<p>Closing as a wontfix, but this conversation is good to have on the record.<p>"""
评论 #3381653 未加载
评论 #3381861 未加载
评论 #3396094 未加载
评论 #3382080 未加载
评论 #3381892 未加载
gcv超过 13 年前
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.
评论 #3380467 未加载
rayiner超过 13 年前
Scheme got this right in 1970. There is no excuse to design a new language this way.
评论 #3380087 未加载
评论 #3380336 未加载
limeblack超过 13 年前
Another Issue:<p>Although the following examples could become unambiguous with parenthesis, these examples demonstrates how a trivially overlooked ending delimiter further complicated the language. Not only is the intent of the CoffeScript code unclear in the examples below but the slight variation in the CoffeScript, produces radically different output. The CoffeeScript differences are so small it would be easy for someone to add accidentally while editing. Anonymous function passing and function calling in Javascript require no additional wrappers or edits, while in CoffeeScript you must add special case clarity.<p><a href="http://img542.imageshack.us/img542/7379/coffeescripttojavascrip.png" rel="nofollow">http://img542.imageshack.us/img542/7379/coffeescripttojavasc...</a>
oinksoft超过 13 年前
<i>@mitsuhiko Not gonna happen ;) Forbidding shadowing altogether is a huge win, and a huge conceptual simplification.</i><p>How arrogant! You'd think he'd step back for a second and consider the suggestion, but it sounds like he's on autopilot.
评论 #3380423 未加载
评论 #3380212 未加载
评论 #3380144 未加载
评论 #3381864 未加载
评论 #3380217 未加载
评论 #3381305 未加载
评论 #3380114 未加载
stoodder超过 13 年前
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.
评论 #3381948 未加载
tjholowaychuk超过 13 年前
I like the look of coffeescript's assignment better, but I cant help but think "let" is much less ambiguous, once you see it you look no further. This reminds me a bit of Ruby, where "foo" could be a function or variable potentially from anywhere so it's a little unclear although better looking.
leafo超过 13 年前
Look at how MoonScript handles this: <a href="http://moonscript.org/reference/#the_using_clause_controlling_destructive_assignment" rel="nofollow">http://moonscript.org/reference/#the_using_clause_controllin...</a><p>I didn't want to change the default semantics, but I wanted to have a way for the programmer to be safe if they wanted to, so I created the `using` keyword for function declarations.<p>You explicitly declare what you intend to overwrite in the lexical scope, including overwriting nothing at all with `using nil`.
buddydvd超过 13 年前
I found one of the referenced links in Github issue #712 quite interesting:<p><a href="http://www.rubyist.net/~matz/slides/rc2003/mgp00010.html" rel="nofollow">http://www.rubyist.net/~matz/slides/rc2003/mgp00010.html</a><p>Source: <a href="https://github.com/jashkenas/coffee-script/issues/712#issuecomment-979127" rel="nofollow">https://github.com/jashkenas/coffee-script/issues/712#issuec...</a>
评论 #3380779 未加载
gerggerg超过 13 年前
<i>Considering we won't see this changed since the author has already closed the issue and expressed his satisfaction with the current rules this article should at least serve as a reminder for errors not to repeat with the next language someone designs.</i><p>It's open source. Why not fork it and get some like minded coders to change it with you?
评论 #3380479 未加载
评论 #3380418 未加载
danmaz74超过 13 年前
With "var" and shadowing you can still shoot yourself in the foot, it's just the other foot.<p>If you need global variables, it's sensible to just adopt a simple naming convention, like prepending g_ (or whatever pleases you) to all your variables. I already did that with plain JS and it's well worth the "effort".
latchkey超过 13 年前
Kind of a side note to the posting, but I just have to say: Please make your usage of parens consistent. If you aren't going to use them, don't use them everywhere.<p>Here is an example of what I'm talking about:<p>if isAir cx, cy, cz + 1 then addPlane('near', block)<p>Should be:<p>if isAir cx, cy, cz + 1 then addPlane 'near', block<p>Personally, I use them everywhere because I like having the stronger visual clue that this is a method I'm calling. I think making them optional in CS was a bad idea.<p>if isAir(cx, cy, cz + 1) then addPlane('near', block)<p>imho, so much more readable.
评论 #3380116 未加载
showell30超过 13 年前
CoffeeScript's approach toward top-level variables is quite elegant and simple. When you declare a variable at top-level scope, it is equally available to all code within that file for both reading and writing, with no strange "nonlocal" or ":=" syntax to complicate manners.<p>Once you understand the reach of CoffeeScript's top-level variables, it is easy to write bug-free code. Since you know that top-level variables have wide scope, you simply need to be judicious about putting variables at top-level scope. If a variable is not needed at top level scope, don't put it there.
评论 #3380055 未加载
perfunctory超过 13 年前
This is my biggest problem with CoffeeScript. And the author stubbornly refuses to fix it. Apparently it's some sort of Ruby religion.
shaunxcode超过 13 年前
Here is a ghetto "let" form in coffee<p>((a = 5, b = 6, log = x -&#62; console.log x) -&#62; log a + b)()
cvshepherd超过 13 年前
&#62; 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.<p>I disagree. The simple solution to this is to write tests.
评论 #3382018 未加载
showell30超过 13 年前
FWIW this is how CS works:<p><pre><code> top_level_variable = null f = -&#62; top_level_variable = "hello" f() console.log top_level_variable # prints hello</code></pre>
评论 #3380326 未加载