Closed aurium closed 9 years ago
This feature is available in Javascript, but not in Coffee.
Not true. { s('param'): 'some value' }
isn't valid in either language, and opts = {}; opts[s('param')] = 'some value'
works in both languages.
Though ES6 will have computed keys. We should be aware of CoffeeScript's coming obsolescence if it doesn't adapt.
ES6 computed keys will be available in Firefox 34: https://developer.mozilla.org/en-US/Firefox/Releases/34#JavaScript.
Yeah it'd be nice to have this. Either with the ES6-style brackets { [key()]: val }
or a more CS-style interpolation delimiters { #{key()}: val }
I don't like @Argorate's sugar, because it looks like prototype sugar, and may cause mistakes. I believe @akre54 comes with a perfect coffeeish syntax #{...}
, despite the conflict with the coffee comment.
On other rand @Argorate compatible compilation for "old" javascript is the same as i was thinking. Someone see any problem on the translation above?
myObj =
x: 1
#{name+i}: 'some value' # as we can see the comment tokenization
#{name+j}: 'other value' # must be updated with this proposal.
somekey: someValue + myObj.x
compiles to:
myObj = {
x: 1
};
myObj[name+i] = 'some value';
myObj[name+j] = 'other value';
myObj[somekey] = someValue + myObj.x;
somekey: someValue + myObj.x
=>myObj[somekey] = someValue + myObj.x;
We can't just break the unquoted syntax unfortunately. That's the reason for the delimiters in the first place.
I'd rather see that input compile to:
myObj = {
x: 1,
somekey: someValue + myObj.x // (runtime TypeError)
};
myObj[name + i] = 'some value';
myObj[name + j] = 'other value';
For the record this is Traceur's output.
If we're bike-shedding, can I throw in hash comprehensions again? It'd be nice if we could naturally extend the key expression syntax to comprehensions, one day.
That seems like a real slippery slope with some ugly unintended consequences.
Dynamic keys are a much more modest and useful addition.
Agreed. I just meant that it'd be worth leaving 'space' in the syntax for comprehensions, for the future, but it shouldn't get in the way of key expressions.
@aurium : yes but in this use case, we will never call "prototype", so I think it's not realy in conflict, but the sugar is not realy important for me, I just hope CS will add one ;)
I’d vote for "a#{b}c": value
to compile to {["a" + b + "c"]: value}
. Just like yield
, this would be a feature that works only in supporting environments; it’s up to the developer not to use it if support for an older environment is needed. No need to a any new syntax.
@lydell: I like that.
@lydell, but, unlike yield
, this is a feature that can be easily implemented with ES3.
I'd vote for using the same syntax and a similar implementation than LiveScript (see "Dynamic Keys"), where:
myObj =
x: 1
"#{name}#{i}": 'some value' # Using string interpolation.
(name + j): 'other value' # Using a parenthesised expression.
somekey: someValue + myObj.x
Compiles to:
// Generated by LiveScript 1.3.1
var myObj, ref$;
myObj = (ref$ = {
x: 1
}, ref$[name + "" + i] = 'some value', ref$[name + j] = 'other value', ref$.somekey = someValue + myObj.x, ref$);
(the output probably needs better whitespace handling)
I like the LS syntax because dynamic string literals look like strings, which is the benefit of string interpolation in the first place; and because it also allows using any value as a key (using the parentheses syntax), which in turn would be useful if we want to support Symbol properties at some point:
countdown =
(Symbol.iterator): *->
yield 3
yield 2
yield 1
# Assuming this compiles to JS's `for ... of`
for n of countdown
console.log n
We must not forget #786 and #1731, though.
Good point about Symbol
keys. That means that we need to support an alternate syntax in addition to string interpolation. Both old CoffeeScript and @epidemian used ()
. An argument for this syntax is ease of implementation, as said in https://github.com/jashkenas/coffeescript/issues/786#issuecomment-484874:
"#{key}": val
Lexer converts interpolated strings into parenthesized concatenations, so that's actually the same thing for parser.
Another option is to use ES6-style []
notation. An argument for this is: Less syntax to learn.
Which is better?
We don't need to worry about Symbol keys — they're probably going to end up being considered a "nasty" part of JavaScript that CoffeeScript can enthusiastically avoid.
"#{key}": val
Is probably the best syntax. In an alternate universe, something like:
key: val
... might be preferable, but that ship has sailed.
I vote for []
syntax. For majority of my use cases it's shorter by 3 characters comparing to "#{}"
syntax. Also is compatible with the ES6 syntax, which means it will gain more familiarity. Moreover, I think it is more intuitive, as it's analogous to the property access syntax:
foo = { bar: 123 }
foo.bar
foo = { [bar]: 123 }
foo[bar]
foo = { "#{bar}": 123 }
foo"#{bar}" # not quite, looks like tagged template string, also doesn't work
foo = { ["#{bar}"]: 123 }
foo["#{bar}"]
If string interpolation is needed, it can still be used like this ["#{}"]
.
Optionally the "#{}"
syntax could be implemented in addition, because they don't collide with each other.
Yes, if we're adding new syntax in addition to interpolation it should definitely be []:
since:
'a': b
works, c.'a'
should work. Since c[a]
works, [a]: b
should work.@lydell Oh I'm sorry, I didn't notice, that the "#{}"
syntax is already implemented, I thought that it is still an open debate.
But still, I think the []
syntax for computed properties would be a nice addition, for reasons you stated :)
Let's not add new syntax for dynamic keys at the moment. If we end up needing it, we can add it later.
This feature is available in Javascript, but not in Coffee.