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

allow const keyword to evaluate when --nodejs --harmony is used #3571

Closed
rebelwarrior opened this issue Aug 7, 2014 · 34 comments
Closed

allow const keyword to evaluate when --nodejs --harmony is used #3571

rebelwarrior opened this issue Aug 7, 2014 · 34 comments

Comments

@rebelwarrior
Copy link

@rebelwarrior rebelwarrior commented Aug 7, 2014

Hi I'm using the examples from PragProg's "NodeJS done the right way".
Hit this problem they are using the --harmony flag to use ECMA6's features.
Figured out how to pass the flag to coffeescript using: coffee --nodejs --harmony
This then throws an error:

error: reserved word "const"
const fs = require('fs')
^

for this line of code:
const fs = require('fs')
however this one executes correctly:

eval('const fs = require("fs")')

I believe the coffeescript parser is stopping on the 'const' keyword irrespective of the --harmony flag being passed.

@garrett-gottlieb
Copy link

@garrett-gottlieb garrett-gottlieb commented Oct 15, 2014

+1

1 similar comment
@luisfarzati
Copy link

@luisfarzati luisfarzati commented Dec 31, 2014

+1

@epidemian
Copy link
Contributor

@epidemian epidemian commented Dec 31, 2014

Honestly, i don't see how this would improve the language.

The MDN article on const doesn't mention the rationale for adding the construct to JavaScript nor does it give any useful example of it. It merely describes what it does.

I feel like, as many other recent additions to JS, const is a case of feature creep; of JavaScript borrowing concepts that don't fit well with its design or are simply bad.

It'd be nice to have variables be immutable by default, only assigned upon their initialization, and a special form for immutable variables, like mut a = 42 or maybe different symbols for denoting declaration/initialization and assignment like b = 0; b := 1 if cond. But it's probably too late for that now.

But having const be the special case that needs a modifier is not a good idea. Most variables are never reassigned after initialization:

inventDrink = (name) ->
  alcohol = Math.random() * 30
  {name, alcohol}
names = ['Cucumber Cognac', 'Vanilla Crush', 'Sugar Nectar']
drinks = (inventDrink name for name in names)

So should code done "the right way" be riddled with const then?

const inventDrink = (const name) ->
  const alcohol = Math.random() * 30
  {name, alcohol}
const names = ['Cucumber Cognac', 'Vanilla Crush', 'Sugar Nectar']
const drinks = (inventDrink name for name in names)

That'd be ridiculous.

That being said, i feel like i'm probably missing something. I'd like to see a good example where the benefits of using const in CoffeeScript would outweigh its drawbacks (boilerplate and increased complexity).

@luisfarzati
Copy link

@luisfarzati luisfarzati commented Dec 31, 2014

I agree. Indeed, if we want to go the "right way", we need to use way more consts than vars in our code (although I don't really mind, it's just a keyword vs another, not that we are cluttering the code). The same happened to me with Java, where I found myself declaring lots of final variables. I reckon it doesn't provide any real value when considering benefits vs cost of implementation.

@pflannery
Copy link

@pflannery pflannery commented Mar 26, 2015

It'd be nice to have variables be immutable by default, only assigned upon their initialization, and a special form for immutable variables, like mut a = 42 or maybe different symbols for denoting declaration/initialization and assignment like b = 0; b := 1 if cond. But it's probably too late for that now.

Yeah probably too late, my impression is that let = mut and const tells the compiler that this variable will always stay the same type and gives a compiler confidence to fully optimize without having to constantly second guess its type identity. It will be interesting to see what performance we get by using const when ES6 (aka ES2015) is over the bridge. I'm not seeing an optimization boost in native V8 yet but more of a on-par performance between let and const.

I found this a pretty good write up for let and const - https://strongloop.com/strongblog/es6-variable-declarations/

@epidemian
Copy link
Contributor

@epidemian epidemian commented Mar 26, 2015

[...] my impression is that let = mut and const tells the compiler that this variable will always stay the same type and gives a compiler confidence to fully optimize without having to constantly second guess its type identity.

I don't expect to see code using const running faster than the equivalent code using var on any JS engine. If a variable is assigned only once, then there's no need to "constantly second guess its type"; the engine can treat it the same as a constant.

@maximzavadskiy
Copy link

@maximzavadskiy maximzavadskiy commented Mar 24, 2016

@epidemian I have a counter example here, that I just discovered today:

defaultData =
  nestedProp : 5

data = defaultData # By reading this, it seems quite fine and easy
data.nestedProp += 1 # But this will modify defaultData!
@lydell
Copy link
Collaborator

@lydell lydell commented Mar 24, 2016

@maximzavadskiy const would't help in your example.

@vendethiel
Copy link
Collaborator

@vendethiel vendethiel commented Mar 24, 2016

What you're looking for is Object.freeze.

@ghost
Copy link

@ghost ghost commented Mar 30, 2016

+1 for this

1 similar comment
@mallinkbird
Copy link

@mallinkbird mallinkbird commented Apr 4, 2016

+1 for this

@sanzaru
Copy link

@sanzaru sanzaru commented Apr 4, 2016

+1

@vendethiel
Copy link
Collaborator

@vendethiel vendethiel commented Apr 4, 2016

you realize there's even a button on github to "+1" now, right?

@ghost
Copy link

@ghost ghost commented Apr 4, 2016

Didn't know that, thanks!

@hooddanielc
Copy link

@hooddanielc hooddanielc commented Apr 13, 2016

I think const is great. Using the keyword const gives me confidence that the reference will never be reassigned. I use it for defensive programming style. I believe it prevented me from creating software with hard to debug issues. For example, lets say a developer needs to detect an users year of age before the user enters a pornographic site using moment.js library.

coffeescript version

age = 18

javascript version with strict mode enabled

const age = 18;

The developer decides to put a global variable in the window object for required age and references that to block underaged users. Now lets say 6 months later the developer implements functionality to fade all submit buttons out on click.

coffeescript version

# how much time for animation
age = 100

$(document).ready ->
  $('button[type="submit"]').on 'click', (e) ->
    $(e.target).fadeOut age

javascript version with strict mode enabled

// how much time for animation
const age = 100

$(document).ready(function () {
  $('button[type="submit"]').on('click', function (e) {
    $(e.target).fadeOut(age);
  });
});

WOOPS, looks like the developer accidentally blocks all users from entering a pornagraphic site because they were using coffeescript. However, the es6 javascript compiler warned the developer because const keyword was being used.

This is why I would like to see the const keyword in coffeescript.

@debrice
Copy link

@debrice debrice commented Apr 29, 2016

@hooddanielc it's likely that a website config will be hosted on an object. For example, a gambling website could have different limitations per country:

const config = {
    US: { minAge: 21 },
    FR: { minAge: 16 }
};

as explained above, using const here only prevents you from re-assign the variable, it wont prevent mutation.

config.US.minAge = 12; // this would work just fine

Sadly, const is likely to be misinterpreted and give a false sense of security.

@akre54
Copy link

@akre54 akre54 commented Apr 29, 2016

Yeah keep in mind any checks that are client-side only can be easily bypassed using the developer tools (or any other method). This is not just a coffeescript issue. If you have critical data / checks on your client side code they can and will be bypassed by someone who cares enough.

@algesten
Copy link

@algesten algesten commented Apr 29, 2016

I don't understand why people keep giving this deep object example as some kind of counter argument to const. yeah I get it. it's not a true immutable. can we move on now?

Why must coffee prevent me from using it even for the very helpful case of avoiding accidental variable name clashes?!

@akre54
Copy link

@akre54 akre54 commented Apr 29, 2016

Because coffeescript doesn't have block scoping. It views variable shadowing as a Bad Part of javascript. See Jeremy's many posts on the topic, there are valid reasons for this decision.

@algesten
Copy link

@algesten algesten commented Apr 29, 2016

ok. it was decided not being able to distinguish between variable declaration and reassignment is a good thing and therefore we must also avoid const.

@akre54
Copy link

@akre54 akre54 commented Apr 29, 2016

It doesn't have var, why would it have const? This has been discussed.

@dadleyy
Copy link

@dadleyy dadleyy commented May 6, 2016

for what its worth, I wouldn't mind if variables in all caps became const-ed:

WHITESPACE = /^[^\n\S]+/

becomes

const WHITESPACE = /^[^\n\S]+/;

but I would not be inclined to see const get added to coffeescript itself.

@rebelwarrior
Copy link
Author

@rebelwarrior rebelwarrior commented May 6, 2016

But it does generate "Var" in the bare JS it generates. It does not generate "const" even when I would like to.

Sent from my mobile.

On Apr 29, 2016, at 5:29 PM, Adam Krebs notifications@github.com wrote:

It doesn't have var, why would it have const? This has been discussed.


You are receiving this because you authored the thread.
Reply to this email directly or view it on GitHub

@epidemian
Copy link
Contributor

@epidemian epidemian commented May 10, 2016

for what its worth, I wouldn't mind if variables in all caps became const-ed

Maybe instead of that the CS compiler could error when trying to re-assign capitalized variables (kinda like what Ruby does):

MESSAGE = 'hello'
foo = -> 
  MESSAGE = 'bye' # Error: cannot reassign MESSAGE constant.

Same thing would apply to classes as they are usually declared using ThisNamingConvention.

@digitaldesigndj
Copy link

@digitaldesigndj digitaldesigndj commented Jun 10, 2016

@dadleyy UPPERCASE is completely backwards incompatible (@epidemian O.o). I mean, I don't write that code, but it's a big world out there. I don't see the advantage of UPPERCASE over const. Wait, terseness... yummy yummy terseness... but wait... pinky abuse... (all torn up inside)

@carlsmith
Copy link
Contributor

@carlsmith carlsmith commented Jun 15, 2016

The idea that you can use const to "avoid accidental variable names clashes" doesn't make sense. Having to think about which vars actually vary, and then label the constants, and update the labels whenever the code changes, is a lot of effort to avoid accidentally using a name that's already visible in the current scope. You should already know which variables are visible, else you are not familiar enough with the code or the runtime to competently edit that code anyway. It seems like bad practice to use const defensively, especially as it doesn't prevent you from clobbering any of the variable variables. It's a pointless safety net, which is full of big holes.

If I understood their motivation, ES6 was designed to allow new languages to be implemented more easily, and has features that mostly exist for that use case. Constants make more sense in that context, and shouldn't be used all over your codebase. IMO.

@rebelwarrior
Copy link
Author

@rebelwarrior rebelwarrior commented Jun 16, 2016

Really the problem is that const can't be used at all in coffeescript which means it is taking a hard opinionated stance that it is a bad part, nay a terrible part of JS.
I don't think so. May not be a recommended part or an optimal one but by banning it you loose a feature of Coffeescript which is available in JS.
It is stuff like this that has made Coffeescript loose relevance vs plain JS.

Sent from my mobile.

On Jun 15, 2016, at 8:02 AM, Carl Smith notifications@github.com wrote:

The idea that you can use const to "avoid accidental variable names clashes" doesn't make sense. Having to think about which vars actually vary, and then label the constants, and update the labels whenever the code changes, is a lot of effort to avoid accidentally using a name that's already visible in the current scope. You should already know which variables are visible, else you are not familiar enough with the code or the runtime to competently edit that code anyway. It seems like bad practice to use const defensively, especially as it doesn't prevent you from clobbering any of the variable variables. It's a pointless safety net, which is full of big holes.

If I understood their motivation, ES6 was designed to allow new languages to be implemented more easily, and has features that mostly exist for that use case. Constants make more sense in that context, and shouldn't be used all over your codebase. IMO.


You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or mute the thread.

@realJoshByrnes
Copy link

@realJoshByrnes realJoshByrnes commented Jul 24, 2016

Is there a good reason not to switch the 'var' ouput to 'const' and 'let' ?

Perhaps with a flag - eg, --es6-vars and change UPPERCASE to const? Thoughts?

@carlsmith
Copy link
Contributor

@carlsmith carlsmith commented Jul 24, 2016

The main reason is just a general aversion to compilation flags. They've always been rejected in the past. Still, they haven't been ruled out totally, and ES6 support will probably force the issue. It's difficult to see how CS classes can become compatible with JS classes without a breaking change, so CoffeeScript will almost certainly have to add compiler flags, or be replaced by a new dialect or language.

@carlsmith
Copy link
Contributor

@carlsmith carlsmith commented Jul 24, 2016

-1 on forcing constants to be uppercase. Most functions will be constants, and we don't want every function to have a LOUD_NAME. We also wouldn't be able to distinguish between class names and the names of regular functions if they all have to be uppercase. We also use camelCase a lot in CoffeeScript, and would be forced to use underscores if we only have uppercase constant names.

A constant assignment operator has been discussed elsewhere, so you'd do something like:

i = 0
pi := 3.141

A better looking operator would be nice, but it's a much less radical change at least.

@realJoshByrnes
Copy link

@realJoshByrnes realJoshByrnes commented Jul 24, 2016

I get what you're saying, but I still think it's a better option than what we have right now.

@bjmiller
Copy link

@bjmiller bjmiller commented Jul 25, 2016

Can people please stop pushing this issue? var, let, and const are all the same in transpiled code. The purpose of let and const is to prevent human error when writing code directly in JS. Their utility is almost completely obviated by CS.

@rebelwarrior
Copy link
Author

@rebelwarrior rebelwarrior commented Jul 25, 2016

Unless of course you use CS to write JS that will go into other ppls code. Then the lack of "let" "const" etc is a severe deficiency.
I get it that's not where CS wants to go.
I'm over it. I moved on to elm and JS6.

On Jul 24, 2016, at 9:41 PM, Brian Miller notifications@github.com wrote:

Can people please stop pushing this issue? var, let, and const are all the same in transpiled code. The purpose of let and const is to prevent human error when writing code directly in JS. Their utility is almost completely obviated by CS.


You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or mute the thread.

@GeoffreyBooth
Copy link
Collaborator

@GeoffreyBooth GeoffreyBooth commented Apr 18, 2017

There was much debate about let and const as part of designing CoffeeScript 2, and it was decided that they should not be supported: http://coffeescript.org/v2/#unsupported-let-const

See also coffeescript6/discuss#31 and coffeescript6/discuss#35

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

Successfully merging a pull request may close this issue.

None yet