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 use of JS (non-coffee) keywords as identifiers #1452

Closed
michaelficarra opened this issue Jun 20, 2011 · 17 comments
Closed

allow use of JS (non-coffee) keywords as identifiers #1452

michaelficarra opened this issue Jun 20, 2011 · 17 comments

Comments

@michaelficarra
Copy link
Collaborator

By way of unicode escape sequences in identifier names. See section 7.6 for the identifier requirements.

So the coffeescript var = 7 can become var va\u0072 = 7. This will alow the use of the following currently reserved words as identifiers:

  • case
  • default
  • function
  • var
  • void
  • with
  • const
  • let
  • enum
  • export
  • import
  • native

We may, however, want to keep some of these reserved for later use by coffeescript (probably void, maybe const or default).

@alpha123
Copy link

I like this, though compiling to something like var$ instead of fooling around with Unicode escapes seems better.

@michaelficarra
Copy link
Collaborator Author

@alpha123: the problem with those solutions is that any alternative identifier that we use takes the place of some other identifier. So, in other words, what would var$ compile to? Unicode escapes allow us to not interfere with any other variable names.

@alpha123
Copy link

@michaelficarra: The ECMAScript spec (3rd edition anyway) says the $ character is intended for use in generated code. Obviously some popular libraries ignored this, so theoretically you could have clashes, but putting it at the end reduces those greatly and is good for interoperability with JS.

Let's say you have something like var = 10 and it compiles to var va\u0072; va\u0072 = 10;.
Not only does this waste bytes and make the generated code way less human-readable, it makes it really unpleasant to access from JS. Compiling to something like var var$; var$ = 10; seems way better IMO.

Oh, and I just discovered that Unicode escapes break Google Closure somewhat, which compiles var va\u0072; va\u0072 = 10; into var var; var = 10;. This is only true for global variables however.

@michaelficarra
Copy link
Collaborator Author

But when given the option between reduced clashes (unacceptable) and no clashes (perfect), we'd obviously want to go with no clashes.

On your second point, we would still have pretty output in all compilations that are allowed today. We would be adding the ability to use these JS keywords as identifiers and the only negative is that they don't compile to a pretty-looking name. I can live with that, and so can somebody using these identifiers.

I will file a bug with closure compiler. We should hold off on this feature until that bug is fixed.

edit: Filed bug #493.

@thejh
Copy link
Contributor

thejh commented Jun 21, 2011

We could instead/additionally use some crazy unicode character that you can see as one character in every viewer - for example, the first character of "coffeescript" in a circle - no programmer would ever put something like that in his code, right?

var var$©;

or

var var©;

@michaelficarra
Copy link
Collaborator Author

@thejh: That's not a valid identifier, you'd actually have to use the escape sequence for it. Nice idea, but it wouldn't work.

@jashkenas
Copy link
Owner

I'm afraid this one is a wontfix, Michael -- it totally destroys API compatibility between CoffeeScript and JavaScript. In my hypothetical CoffeeScript library:

Twitter.function = ->
  api.get ...

And then, when you try to use my library from JavaScript:

Twitter.function()
>> SyntaxError: Parse error

Reserved words should not be used as identifiers.

@michaelficarra
Copy link
Collaborator Author

@jashkenas: bad example?

$;node
> var Twitter = { function: function(){ console.log('works'); } };
> Twitter.function()
works
> 

I don't see the compatibility problem. var is just a syntactic sugar over va\u0072. I think that goes along with all the other coffeescript features.

@jashkenas
Copy link
Owner

Safari:

var Twitter = { function: function(){ console.log('works'); } };
Twitter.function()
SyntaxError: Parse error

... does not work.

@michaelficarra
Copy link
Collaborator Author

Safari's wrong here:

See 11.2.1, which says that a dot is followed by an IdentifierName (not Identifer, which can't be a reserved word) and 7.6 which defines IdentifierName and Identifier.

edit: But we weren't talking about properties anyway, we were talking about standalone identifiers.

@jashkenas
Copy link
Owner

As usual, we don't give a damn about what ES5 says here -- what matters is what runs in browsers, including IE6 and IE7, even.

@michaelficarra
Copy link
Collaborator Author

I don't have a way to test IE right now, but the spec hasn't changed with this regard since ES3, back in 1999. So it's very possible (likely?) that those older browsers support unicode escape sequences in identifiers. Can you provide an example of any browser that doesn't support them? Re-opening, since this was closed without a (related) explanation. Feel free to close it again if browser support is found to be lacking or there's some reason this practice should be disallowed.

@thejh
Copy link
Contributor

thejh commented Jun 21, 2011

OK, © doesn't work, but, for example, delta (Δ) seems to work at least in v8 (although I didn't read the spec).

@lluchs
Copy link

lluchs commented Jun 21, 2011

IE6 doesn't seem to support them:

var va\u0072 = 'it works!';
document.write(va\u0072);

gives an error on l. 1 col. 5: Expected identifier

Edit: even IE9 throws exactly the same error

@jashkenas
Copy link
Owner

Feel free to close it again if browser support is found to be lacking or
there's some reason this practice should be disallowed.

It breaks API compatibility with JavaScript: JS cannot reference a variable, or call a function, by the same name that CoffeeScript identifies it with. You would never want to write a library that took advantage of this feature.

@alpha123
Copy link

@thejh: What the heck, that actually works. Tested in FF5, Opera 11.11, Chrome 14, IE9, and IE9 in IE7 compatibility mode. Dunno if it truly works in older IE versions though, IE compatibility mode tends not to work so well when it comes to JS.

@satyr
Copy link
Collaborator

satyr commented Jun 22, 2011

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

No branches or pull requests

6 participants