-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CS2 Discussion: Features: let/const/var #4900
Comments
From @carlsmith on July 12, 2016 0:24 Whether we have We should keep this discussion about Should we even keep CoffeeScript's nonlocal assignment rule? If were making breaking changes, we should consider changing that as it was quite controversial - all assignments are currently nonlocal. The name lookup starts locally, and works outwards until it finds the name and reassigns it. If it doesn't find the name, the assignment is local. In Python, all assignments are just local, which is what you normally want to happen. Lexical scope exists to keep variables locally defined. You never have to worry about clobbering something in the global scope with a local variable like you do in JS and CoffeeScript. The problem with Python is that it uses BikesheddingI think all assignments should be local, and we should have a variable available inside each function, just like You would use
If you had functions nested inside of each other, each lexical scope would have its own Assignments should have always been local, and it's natural to extend the idea behind |
From @rattrayalex on July 12, 2016 4:55
My hunch is the |
From @rattrayalex on July 12, 2016 4:58 I don't think there's much reason to use If adding a An alternative would be to have all variables by |
From @DomVinyard on July 12, 2016 8:24
That sounds like an absolute nightmare. Hard-coding your depth in the scope. It will be very easy to reimagine all of coffeescript's features under the mandate of 'allowing breaking changes' - but I think there is a good case for picking a few bits of low hanging fruit and then addressing the rest once we're up and running. let/var/const would be a good candidate for leaving alone, i think. |
From @carlsmith on July 15, 2016 16:11 I don't see a problem with absolute scope references, when scope is already lexical. Still, we have more worthwhile stuff to discuss, so yeah, forget it. |
From @JimPanic on July 19, 2016 9:17 I really want to see Regarding scoping, I'm in favour of leaving lexical scope as-is as well. In the future it might be a good idea to make |
From @carlsmith on July 19, 2016 13:20 Hi @JimPanic, welcome.
You misunderstood the problem I was trying to address. CoffeeScript will always have lexical scope as-is. No one wants to change that. It's the way CoffeeScript mandates that all assignments are nonlocal that's the issue. It's always been a pretty controversial feature, and one of the most popular criticisms of CoffeeScript. For an example of the feature, here's two seemingly similar blocks of code, the first is CoffeeScript, the second is Python. They do different things though: x = false
do ->
x = true
console.log x # true
console.log x # true In CoffeeScript, the outer x = False
def f():
x = True
print x # True
f()
print x # False We can avoid clobbering x = false
do (x) ->
x = true
console.log x # true
console.log x # false Lacking any real evidence, I can just say from experience with Python that nonlocal assignment is pretty rare. You almost always want assignments to be local. I assume @jashkenas only went with nonlocal assignment to avoid having to have declarators. There's no other sane reason to do it. If we're going to change the language design to introduce declarators, then we should definitely make assignment local by default and have a declarator for nonlocal assignment. We don't need Python's If Even if we keep assignments nonlocal, if we introduce declarators, we would really need declarators for The benefit of having block-scope in CoffeeScript is slim. We can always create a new scope with if foo
let x = true
let y = false But, we can already do this anyway: if foo then do ->
x = true
y = false JavaScript became considerably more complicated by introducing I personally think Taking declarators from JavaScript requires changing them to fit CoffeeScript's nonlocal assignment feature, which may in turn require any declarators to be renamed for their new semantics, so we'd basically need to define our own declarators from scratch. And we really should try and do everything we can to avoid introducing declarators, given that they have been rejected from CoffeeScript for seven years, and they make everything look like Java. jQuery ->
local const square = (x) -> x * x |
From @JimPanic on July 19, 2016 13:58 @carlsmith You are right, I did misunderstand. I always thought CS was favouring the innermost scope in assignments. Lucky me it didn't bite me so far. |
From @carlsmith on July 19, 2016 14:3 @JimPanic :) It's not obvious what CoffeeScript is doing, especially when it seems to be doing what you'd expect, coming from other languages. It doesn't bite that often, but when it does, it can be totally baffling. |
From @rattrayalex on July 20, 2016 20:25 Thanks very much @carlsmith for the terrific explanation there. Didn't understand that bit myself so well till now 😄 I do agree that it would likely be too ambitious to change how scoping works, unless we can simplify the coffeescript compiler by staying closer to JS's behavior. |
From @rattrayalex on July 20, 2016 20:27
@JimPanic can you elaborate? I intuitively feel the same way – I enforce |
From @rattrayalex on July 20, 2016 20:39 Any thoughts on x := 7 # const x = 7 And all other |
From @rattrayalex on July 20, 2016 20:43
@DomVinyard re-reading this, I'm not sure I understand what you originally meant. Can you clarify? |
From @carlsmith on July 20, 2016 21:29 Adding a constant operator is easier than adding declarators. It changes the language less. The operator is ok, but will get a bit messy when its |
From @JimPanic on July 22, 2016 8:38 @rattrayalex It helps avoiding so many bugs and enables a more declarative way of coding, which in turn helps keep code readable and (more) testable. How do you enforce |
From @JimPanic on July 22, 2016 8:39 @carlsmith I was thinking the same; a different assignment operator would go well with the CS syntax as it is now, since there are no declarator keywords. Why the question mark in |
From @carlsmith on July 22, 2016 12:55 @JimPanic - My bad: I got it back-to-front (I rarely use the feature this way), but you have an existential assignment operator in CoffeeScript that looks like |
From @carlsmith on July 22, 2016 13:26 We could figure out from static analysis whether a name is assigned more than once, and make names that are never reassigned constants automatically, but expect JavaScript engines already do this, so any efficiency gains would likely be negligible. More importantly, people want explicit constant assignment/declarations to communicate that constraint to other programmers. Given that it's a popular CoffeeScript feature request, and already part of ES6, explicit constants should really be supported somehow. There's an argument for getting rid of the If we just kept the current i = 0
pi is 3.141 Then If we do a backwards incompatible CoffeeScript, we should definitely fix anything that is accepted as broken and easy to fix. Removing It's also worth mentioning that Python has an a = b = []
a is b # True
a, b = [], []
a is b # False Using |
From @DomVinyard on July 22, 2016 14:25 Coffeescript succeeded, at least partially, because it traded out efficiency optimisations for simplicity in a bunch of contentious but elegant ways. Not distinguishing between let and const fits that core simplicity brief. Perhaps this means that a few edge-projects will have to use vanillaJS for certain classes of application because the overhead of trading out lets for consts would trip the project from acceptable into unacceptable but I think that is a reasonable cost to keep things simple. Avoiding having to add a new operator is worth fighting hard for in every case.. if CS is to retain its CSiness. |
From @DomVinyard on July 22, 2016 14:40 @carlsmith Firm -1 from me for redefining is. |
From @rattrayalex on July 22, 2016 16:24
Yes – it's an ESLint setting to always use const unless you redefine the variable later.
I don't think an existential constant assignment operator makes sense 😉. |
From @rattrayalex on July 22, 2016 16:55
I'm increasingly convinced of this as well personally. Should probably add to coffeescript6/discuss#8.
I disagree with this sentiment, actually. While maintaining a decent degree of backwards-compatibility would be nice, I don't think we should shy away from adding new features, especially those that are part of ES6. The number one purpose of this org is to ensure that CoffeeScript isn't behind ES6 at all – that anything* you can do conveniently in JavaScript, you can do at least as conveniently in CoffeeScript. Furthermore, language innovation is a core aspect of the "CSiness" of CoffeeScript IMO. Jeremy combined the most convenient language features he could find from other languages, made it easy to write good javascript, and added some new ideas into the mix as well. We should certainly think really hard about whether any new features are worth doing – and focus on compatibility with ES6 first – but I also don't think it's something we should shy away from. * Anything that you should be doing, anyway. Making "the bad parts" and generally poor programming practices less convenient, or even impossible, is a good thing. |
From @rattrayalex on July 22, 2016 16:59
I personally agree. However, to keep a healthy environment where people feel comfortable voicing new ideas they might not be 100% comfortable with yet, let's try to back up -1's with a few calm reasons. In this case, my reason is primarily difficult of porting – redefining a language keyword to something completely different could make updating quite difficult, as you'd have to both translate all existing I also happen to think it'd be a bit less readable than something with symbols, given the ubiquity of the |
From @rattrayalex on July 22, 2016 17:1 My understanding is the primary objection to I think the leading alternative at this point would probably be to just pass Thoughts? |
From @carlsmith on July 22, 2016 22:0
I didn't think about that. Sorry about the noise then. I mentioned not using that feature much when I misspelled the operator I'm with @rattrayalex on adding new features, but feel pretty strongly that we should stick to things that are just sugar for well established idioms or that have already been standardised by ECMA. CoffeeScript should make one big breaking change, then treat TC39 as our standards process. Now that CoffeeScript has inspired JavaScript to evolve, we can co-evolve with JavaScript in a way Jeremy couldn't in 2009. So, yeah - sorry to ramble - assuming there will be no need to have an existential constant assignment operator, then I would personally be ok with
I still feel strongly that we should avoid declarators if at all possible. It changes the language, and we use assignment expressions in lots of places where they need to be concise, not just in standalone statements.. Also, do we need a story for constant function parameters, or can you just not define a parameter as a constant? |
From @rattrayalex on July 23, 2016 2:11
Agreed.
Would you be willing to provide a few quick examples for illustrative purposes?
Well, you can't in es6, so we'd really be going above and beyond if we implemented it in cs6. It's not an unappealing feature imo but probably not something to worry about yet.
Amen.
I really need to learn more about TC39 😃 |
From @carlsmith on July 23, 2016 2:57
I meant using assignment expressions like this: if (stuff = getStuffOrReturnNull) then use stuff
employees = [
ali = new Employee "Ali"
bob = new Employee "Bob"
]
Because assignments are expressions, you can write one anywhere you can write an expression. It can be helpful when you want to make assignments conditionally, and lets us use some shorthand expressions for initialising variables. |
From @carlsmith on July 23, 2016 3:10 On the TC39 comment: I really just meant that we should follow the ECMAScript standards when introducing features that go beyond sugar for common JS idioms. We have the luxury these days of a standards process that moves quickly, releases often and develop editions in parallel. It has some of the best minds in our community, and all the vendors are on board. You can get involved through ESDiscuss, and influence the spec, but for the most part, we don't need to. It works. If Jeremy had followed the spec, we wouldn't have the problem we now have with incompatible classes. Obviously, in 2009, following the spec would have made CoffeeScript suck. |
From @rattrayalex on July 23, 2016 3:13 Wow, I've never seen the https://github.com/michaelficarra/CoffeeScriptRedux/wiki/Intentional-Deviations-From-jashkenas-coffee-script#intentional-deviations might be relevant here once we get into the weeds, especially if we decide to build on CSR. Thanks for sharing the examples! Helpful. |
From @dadleyy on July 27, 2016 6:19 ah. I feel like having it cluttered by |
From @JimPanic on July 27, 2016 6:32 Since the assignment with My problem with inference of I do get your point with all-caps const variables and I've used that in Ruby a lot. But it kind of bugged me to write and read all-caps variable names as well. What do other people think about this? |
From @JimPanic on July 27, 2016 6:35 It all boils down to taste, and I'm frank about it: I don't like all-caps words and I find So basically your proposal would work equally well but I personally don't like it as much. :) |
From @carlsmith on July 27, 2016 6:44 I'm totally against It also destroys all of our naming conventions, which span many languages. |
From @dadleyy on July 27, 2016 6:52 Yeah I didn't realize people were using |
From @carlsmith on July 27, 2016 7:03 One or two is fine, but most names are constants. @rattrayalex - In the example I posted, Why can we not make properties constant? We can make properties of |
From @carlmathisen on July 27, 2016 8:46
Didn't know that - how? |
From @carlsmith on July 27, 2016 9:21 I just meant that global assignments are to properties of the window object, so outside lexical or modular scope, I've tried to read up on this, as it's a bit confusing - you assume it's as simple as it seems - but the usual docs don't dive into any detail. Gonna search ESDiscuss later, and see what's been discussed already. |
From @carlmathisen on July 27, 2016 9:44
I don't think that is the case, because
outputs
outputs |
From @carlsmith on July 27, 2016 12:13 Thanks @carlmathisen. Yep, you're right. I never knew it worked like that. It just never came up. That makes things consistent at least. And the ability to make properties read-only makes ES6 gave JavaScript features we really needed, but also made a pretty messy language even messier :( We ultimately need a new language, with JS bindings, but with its own semantics that refine JavaScript, removing cruft like the special arguments array type and 'temporal dead zones', and fixing coercion and exception handling etc. etc. Once WASM matures, it'll be much easier to do without the performance penalty of using an interpreter VM written in JavaScript instead of just compiling to JS. |
From @DomVinyard on July 28, 2016 1:11
I'm here because I need Coffeescript. And because it would be nice to get a community together again to lovingly support it going forward. It's still my belief that there is no need for a var/let/const distinction in Coffeescript and that 'a variable is a variable' is enormously powerful. |
From @JimPanic on July 28, 2016 4:09
That's certainly true. I hope a few of those messy bits will get cleaned up over time in the next years, though. Given the pace ES is moving at right now, this is not too unlikely.
I think it's a good feature to have as long as you don't have to use it. I do want to be able to use |
From @carlmathisen on July 28, 2016 4:26 But is it a core focus feature, right now? It's absence is certainly not in the way of ES6 compatability, such as classes. IMO it's nice to have at best, not need to have. |
From @JimPanic on July 28, 2016 4:32
It is not listed as the proposed core focus features, but as one of points in the "four core may be too short"-list. Can you maybe head over to the coffeescript6/discuss#8 issue and comment there as well regarding priorities? |
From @DomVinyard on July 28, 2016 8:03
I can fathom the sort of project where the overhead of const over var is a performance bottleneck remedy. I can't fathom why anybody would pick coffeescript for that project. |
From @carlsmith on July 28, 2016 8:45
I was making an observation about what the world ultimately needs. I don't see how your motivations for being here counter that.
The ability to extend ES6 classes is required to use the APIs provided by modern JavaScript libraries. If you don't have that feature, you can't use a growing list of libraries. We don't need constants for ES6 interop. It's not about personal preferences. We need ES6 classes to avoid becoming obsolete, but constants are entirely optional. |
From @rattrayalex on July 28, 2016 10:21
Let's talk priorities on the priorities thread, and avoid shooting down ideas just because they're not "absolute must-haves" |
From @carlmathisen on July 28, 2016 9:29 You're right @rattrayalex, sorry about the tangent. |
From @GeoffreyBooth on Sep 6, 2016 12:03 Carrying over a discussion from coffeescript6/discuss#30, is interoperability affected if we don’t add support for One sort-of case I can think of is mentioned in this comment on the modules PR. Basically, anything you import is essentially a import foo from 'lib'
|
From @zeekay on Sep 6, 2016 17:23
I'm not a fan as As
This is perfectly acceptable and matches JavaScript which is preferable to new syntax. Coming from Python, CoffeeScript's nonlocal assignment was kind of confusing, at least initially. I no longer find it very difficult to reason about, but I cannot think of a single person I've met who is a fan of it (and of course it's been written about for quite some time, never positively). Personally, I would not mind ditching it in favor of implicit |
From @GeoffreyBooth on Sep 6, 2016 17:57 zeekay I think By nonlocal assignment, I assume you mean CoffeeScript’s habit of creating a |
From @zeekay on Sep 6, 2016 18:48 By nonlocal assignment I was referring to how it's not possible to shadow an outer variable:
Which is the terminology used above in this discussion (as a nod to Python's I would argue that the lack of keywords for declaration was due to lack of necessity (when CoffeeScript was introduced there was only |
From @zeekay on Sep 6, 2016 18:58 As a quick follow-on: I'd be fine with changing declaration behavior. Compiling normal declarations directly to The more interesting bit of the discussion in my mind is what to do (if anything) about CoffeeScript's (for lack of better terminology) nonlocal assignment. It might be nice to introduce
Which would be a better use of |
From @GeoffreyBooth on Sep 6, 2016 23:52 @zeekay may I invite you to open an issue suggesting changing nonlocal assignment? And the community can debate its merits there. This thread covers both explicit |
From @mrmowgli on Sep 7, 2016 16:46 I can see why the const becomes important, especially when dealing with code security. Let being the counterpart to avoid intentional abuse of the browser environment. I don't think anything would directly break, but I do think there is a good reason to include the functionality. Perhaps there are some intelligent rules to creating let assignments automatically. +1 for := assuming let and keeping the const keyword. |
From @rattrayalex on Sep 7, 2016 21:33 @GeoffreyBooth not sure if anyone answered your question:
I don't believe so, no. |
From @carlsmith on Sep 8, 2016 13:54 I can't see any way it could undermine interoperability either. It's the reference that is constant, not the value, and a library wouldn't even see the name, unless you were sharing globals. Every interface is focussed on the values, never the way they're expressed. |
From @rattrayalex on Sep 9, 2016 9:10 My understanding of our consensus:
As such, I am closing this issue for now. If I get sufficient 👎 reactions to this comment, we'll re-open. |
From @GeoffreyBooth on Sep 9, 2016 9:22 If I could amend that consensus a little, @zeekay described an alternate proposal on Gitter that he’s planning to present as a new issue soon, probably this weekend. Basically his point is that the great advantage of let a = 1;
if (true) {
let b = 2;
}
console.log(b); // undefined This is a dramatic improvement over I think we could have both, via
We don’t necessarily need the second operator, if we don’t care to give people a way to force Agreed that we should close this issue though, in favor of coffeescript6/discuss#31 and whatever new issue is created to discuss this “lexical assignment operator”. |
From @DomVinyard on July 11, 2016 12:13
Personally, I believe these should be untouched. I can see that there is a case for implementing const in almost any language remit. But not coffeescript.
Copied from original issue: coffeescript6/discuss#1
The text was updated successfully, but these errors were encountered: