Skip to content
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: const assignment operator #4927

Closed
coffeescriptbot opened this issue Feb 19, 2018 · 30 comments
Closed

CS2 Discussion: Features: const assignment operator #4927

coffeescriptbot opened this issue Feb 19, 2018 · 30 comments

Comments

@coffeescriptbot
Copy link
Collaborator

From @GeoffreyBooth on 2016-09-07 06:49

Branching off from #1 and #30, I thought it would be good to have a thread dedicated to discussing the proposed new operator for explicitly declaring and assigning a variable as a const. This thread is not for debating automatic let assignment, or whether we should change other things related to variable assignment. Just const. For other topics, please comment on other issue threads.

The consensus from #1 seems to be to add an := operator that works like =, but declares and assigns a variable as a const. So:

foo := 42

becomes:

const foo = 42;

This has the advantage that it’s not a breaking change; currently := fails to compile. There is no need to support ?:=, since by definition constants can’t be reassigned.

Nothing else would be changed by adding this new operator. Normal assignment is handled as it is today, with var. Even though using := would cause const to be in the generated output, this feature is “opt in” like modules and the same warning would apply about transpiling CoffeeScript’s output.

If people like the idea but disagree with the syntax, I invite you to propose an alternate syntax that isn’t a breaking change. Simply following ES2015, with a syntax like const foo = 42, is an option since const is already a reserved word in CoffeeScript.

So I think the debate is: should we add this at all? And if so, this syntax or some other backwards-compatible syntax?

@coffeescriptbot
Copy link
Collaborator Author

From @zeekay on 2016-09-07 07:24

I prefer matching JavaScript here. It's less confusing to newcomers, matches compiled output exactly, etc. Seems preferable for a minor ES6 feature of limited utility.

As const is a reserved word passing through const foo = 42 would not be a backwards-incompatible change as it does not currently compile.

I would much rather see := used for let declaration which would make it easy to avoid shadowing outer variables explicitly (and remove one of the greatest gripes with the language).

@coffeescriptbot
Copy link
Collaborator Author

From @GeoffreyBooth on 2016-09-07 07:25

I take it back, I didn’t notice that const was reserved. I’ll update my leading post.

@coffeescriptbot
Copy link
Collaborator Author

From @lydell on 2016-09-07 07:54

I tend to use const for every single variable (except when I more or less have to reassign a variable) when I write ES2015+ code. So I wouldn't the short := operator. But typing const in JS doesn't bother my that much either.

@coffeescriptbot
Copy link
Collaborator Author

From @zeekay on 2016-09-07 08:14

I can see the value of := as a shorthand if it's your default declaration (I would prefer to optimize for let). I tend to use const pretty sparingly in ES2015+ code and other languages (like Go). Top level bindings are about all I ever use const for. Having managed a team of Go developers the last couple years I've not seen it used for much else (but that might be my bad influence on them).

I would still prefer := used elsewhere, I'll submit a proposal for my suggested usage which can be weighed against it's use for const declaration here.

@coffeescriptbot
Copy link
Collaborator Author

From @DomVinyard on 2016-09-07 09:01

I'll drop my opinion on this here by way of completeness (#30). I strongly believe that the concept of an exposed const does not belong in CoffeeScript. Frankly, that it doesn't even belong in a discussion about CoffeeScript.

@coffeescriptbot
Copy link
Collaborator Author

From @rattrayalex on 2016-09-08 04:41

I tend to use const pretty sparingly in ES2015+ code

that's not true for many people; see the discussion in #1 .

Having managed a team of Go developers the last couple years

that's not true for many coffeescript developers either 😉

@coffeescriptbot
Copy link
Collaborator Author

From @rattrayalex on 2016-09-08 04:42

How parseable would const x = ... be?

@coffeescriptbot
Copy link
Collaborator Author

From @GeoffreyBooth on 2016-09-08 04:51

If we could somehow automatically choose var or const (or let) as appropriate, that would seem to be the ideal solution, as then people could continue their blissful state of never having to worry about var, or now const, but still get the (perhaps theoretical, at least for now) gains of code output with consts everywhere. Automatically choosing var or const as appropriate would mean we would need to introduce a flag, since there wouldn’t be new syntax with which people could “opt-in,” like import for modules; but an --esnext flag or similar is probably inevitable at some point anyway.

What’s lost by automatic const assignment is the intentionality that typing const provides in ES2015. It’s telling the runtime, “throw an error if I mistakenly reassign this variable!” I think a lot of people find value in that; though that doesn’t mean it needs to become part of CoffeeScript. We’re not becoming TypeScript anytime soon. Is the lack of this something that people would miss?

I think we could, potentially, automatically assign variables with const. Having just spent way too much time thinking about modules, one of the nice things about variables that are imported is that they’re read-only—consts, essentially. That means that the compiler would never need to look beyond the current file’s scope to determine if a variable in that file should be declared with const or with var/let: if it’s reassigned in this file, it must become a var or let; if it’s not, it can become a const because any other file that imports this one would get it as a const (no matter how it’s declared in this file). Am I correct about this? Is there a scenario I’m not thinking of where the compiler might not be able to tell if a variable ever gets reassigned (something returned from a function, perhaps)?

@coffeescriptbot
Copy link
Collaborator Author

From @rattrayalex on 2016-09-08 05:19

I don't quite see the point in an inferred const? (As discussed elsewhere). If people want pretty output they can use decaffeinate.

@coffeescriptbot
Copy link
Collaborator Author

From @lydell on 2016-09-08 05:55

Personally, I don't care about any theoretical performance benefit or something like that by using const. For me, it's all about stopping myself from re-assigning variables, because I find my code easier to understand then.

@coffeescriptbot
Copy link
Collaborator Author

From @GeoffreyBooth on 2016-09-08 06:01

So @rattrayalex and @lydell want the explicit “I want the compiler to fail if I reassign this variable” while @DomVinyard and @greghuc in #30 want to preserve “I don’t need to think about how my variables are assigned.”

We get the former with := (or a const keyword), and the latter with automatic const. I guess the language could have both, though everyone would need to learn both.

@coffeescriptbot
Copy link
Collaborator Author

From @JimPanic on 2016-09-08 07:00

👍 for explicit

Implicit const is not worth implementing. There is absolutely no benefit to it.

@coffeescriptbot
Copy link
Collaborator Author

From @mrmowgli on 2016-09-10 05:29

+1 for explicit. For both const and let.
I can see some value in having a shorthand, however for const I find that the keyword is actually very descriptive and readable.

Unfortunately it seems that const refers only to the reference of the variable not changing, rather than variable immutability. Perhaps const could pass through, and := could mean the variable cannot be altered. Or since CS could actually clarify this, just use const but add immuteablity.

@coffeescriptbot
Copy link
Collaborator Author

From @GeoffreyBooth on 2016-09-10 23:30

@JimPanic there is actually a benefit to implicit const, but it’s the same benefit from let: block scope. You can run this code in Chrome DevTools console today:

if (true) {
  var a = 1;
  let b = 2;
  const c = 3;
}
console.log(a); // 1
console.log(b); // Uncaught ReferenceError: b is not defined
console.log(c); // Uncaught ReferenceError: c is not defined

Also theoretically runtimes should be more performant with const than var, though I don’t know if such improvements have happened yet. But they should come eventually.

@coffeescriptbot
Copy link
Collaborator Author

From @GeoffreyBooth on 2016-09-12 06:56

I’m starting to think it doesn’t make sense to implement only const. Doing so would mean that one could declare a block-scoped variable—but only via const. (See the variable c in my previous comment.) I think if we’re going to allow block-scoped variables, we need to allow both let and const. I’ve opened #35 for that approach.

@coffeescriptbot
Copy link
Collaborator Author

From @GeoffreyBooth on 2016-09-16 04:02

I’m going to close this in favor of #35, unless anyone objects.

@coffeescriptbot
Copy link
Collaborator Author

From @rattrayalex on 2016-09-16 04:04

I object 😉

const is a separate feature, primarily focused on preventing reassignment, and secondarily about block scoping.

Regardless of whether const is worth implementing, it's worth considering on its own in my opinion.

@coffeescriptbot
Copy link
Collaborator Author

From @GeoffreyBooth on 2016-09-16 04:12

How would you deal with the side effect that outputting const means that variables declared with := would be block-scoped, while variables declared with = would be function-scoped?

@coffeescriptbot
Copy link
Collaborator Author

From @rattrayalex on 2016-09-16 04:19

A line of documentation 😉

@coffeescriptbot
Copy link
Collaborator Author

From @rattrayalex on 2016-09-16 04:20

The ability to declare some variables as block, and some as lexical, is a "feature" of JavaScript, bless-its-heart.

@coffeescriptbot
Copy link
Collaborator Author

From @rattrayalex on 2016-09-16 04:20

And the number of times when you really don't want coffeescript's current scoping, and really want block scoping instead, and can't use const, is probably extremely low.

@coffeescriptbot
Copy link
Collaborator Author

From @GeoffreyBooth on 2016-09-16 04:24

I think if we introduce into CoffeeScript the ability to declare a block-scoped variable, we can’t force it to be unreassignable. If we give people const, we need to also give them let.

Maybe the times when someone would want let instead of var would be low, but I think it’s way too confusing for variable assignment to not offer them that option.

@coffeescriptbot
Copy link
Collaborator Author

From @rattrayalex on 2016-09-16 04:45

If we give people const, we need to also give them let.

In theory, that's true.

In practice, we can give the one without the other, and very few people will run into difficulties.

@coffeescriptbot
Copy link
Collaborator Author

From @rattrayalex on 2016-09-16 04:46

However, if you'd like to propose completely replacing var with let in CS2, that might be reasonable in the other thread.

... in any case, I personally think this thread should be kept alive for discussion, regardless of whether you think it will ultimately make sense to merge.

@coffeescriptbot
Copy link
Collaborator Author

From @GeoffreyBooth on 2016-09-16 04:54

I disagree that the amount of times people would want let would be low. Many of CoffeeScript’s users have some experience with ES2015, and are used to using let and const exclusively for all their variable declarations. If we give them a way to generate const, they’ll also look for a way to generate let, and if they don’t find it they’ll be confused.

I’m not convinced we should mess with variable assignment. Perhaps one = is better than three.

@coffeescriptbot
Copy link
Collaborator Author

From @mrmowgli on 2016-09-16 07:10

We definitely don't want to take away the ability to use var when they expect it. Especially when dealing with closures.

@coffeescriptbot
Copy link
Collaborator Author

From @jcollum on 2016-09-16

Keep in mind I'm not any good at writing transpilers: why not just let people use let/const and default to var if they don't?

let a = 1 # output let
const a = 1 # output const
a = 1 # output defaults to var

@coffeescriptbot
Copy link
Collaborator Author

From @GeoffreyBooth on 2016-09-16

@jcollum there’s no reason the transpiler couldn’t. It was a core design decision of CoffeeScript, though, that developers wouldn’t have to think about variable declaration. That’s why CoffeeScript groups together all variables used in a scope to a var declaration line at the top of each scope. Adding the ability to specify let or const, whether with a keyword or with an operator, violates this design principle.

Not everyone agrees with this design decision, clearly. And they may have more ammo to their argument since ES2015 introduced let and const. But it’s hard to know if this is something we should change, since the agitators are always louder on GitHub than the people who prefer the status quo, even though there may be more people out there who prefer things as they are.

@coffeescriptbot
Copy link
Collaborator Author

From @jcollum on 2016-09-16

I like the design principle of "Use a default but allow people to override it". I'd prefer not to use backticks to override it. 2¢

@coffeescriptbot
Copy link
Collaborator Author

From @GeoffreyBooth on 2016-09-17

See this comment. I really don’t think allowing const without let is feasible, for all the other differences that const has from var aside from unreassignability. I still think we should close this issue and leave coffeescript6/discuss#35 as the only viable option for supporting let/const.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant