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

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.

@garrettg123
Copy link

+1

1 similar comment
@luisfarzati
Copy link

+1

@epidemian
Copy link
Contributor

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

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

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

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

@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 commented Mar 24, 2016

@maximzavadskiy const would't help in your example.

@vendethiel
Copy link
Collaborator

What you're looking for is Object.freeze.

@ghost
Copy link

ghost commented Mar 30, 2016

+1 for this

1 similar comment
@mallinkbird
Copy link

+1 for this

@sanzaru
Copy link

sanzaru commented Apr 4, 2016

+1

@vendethiel
Copy link
Collaborator

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

@ghost
Copy link

ghost commented Apr 4, 2016

Didn't know that, thanks!

@hooddanielc
Copy link

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.

@typehorror
Copy link

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

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

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 commented Apr 29, 2016

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

@dadleyy
Copy link

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

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 [email protected] 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

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

@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

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

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 [email protected] 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

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

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

-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

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

@bjmiller
Copy link

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

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 [email protected] 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

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
Development

No branches or pull requests