-
Notifications
You must be signed in to change notification settings - Fork 2k
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 dynamic keys for object (hash) definition #3597
Comments
Not true. |
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 |
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 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; |
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 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 |
@lydell: I like that. |
@lydell, but, unlike 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 |
Good point about
Another option is to use ES6-style Which is better? |
As discussed in jashkenas#3039 (comment). This is the first step to implement dynamic object literal keys (see jashkenas#3597). This also fixes jashkenas#1392. In short, `super` is now allowed: # in class definitions: class A instanceMethod: -> super @staticmethod: -> super @staticMethod2 = -> super # in assignment where the next to last property is 'prototype': A::m = -> super A['prototype'].m = -> super a.b()[5]::m = -> super A::[x()] = -> super class B @::m = -> super
As discussed in jashkenas#3039 (comment). This is the first step to implement dynamic object literal keys (see jashkenas#3597). This also fixes jashkenas#1392. In short, `super` is now allowed: # in class definitions: class A instanceMethod: -> super @staticmethod: -> super @staticMethod2 = -> super # in assignment where the next to last property is 'prototype': A::m = -> super A['prototype'].m = -> super a.b()[5]::m = -> super A::[x()] = -> super class B @::m = -> super
As discussed in jashkenas#3039 (comment). This is the first step to implement dynamic object literal keys (see jashkenas#3597). This also fixes jashkenas#1392. In short, `super` is now allowed: # in class definitions: class A instanceMethod: -> super @staticmethod: -> super @staticMethod2 = -> super # in assignment where the next to last property is 'prototype': A::m = -> super A['prototype'].m = -> super a.b()[5]::m = -> super A::[x()] = -> super class B @::m = -> super
As discussed in jashkenas#3039 (comment). This is the first step to implement dynamic object literal keys (see jashkenas#3597). This also fixes jashkenas#1392. In short, `super` is now allowed: # in class definitions: class A instanceMethod: -> super @staticmethod: -> super @staticMethod2 = -> super # in assignment where the next to last access is 'prototype': A::m = -> super A.prototype.m = -> super a.b()[5]::m = -> super A::[x()] = -> super class B @::m = -> super
As discussed in jashkenas#3039 (comment). This is the first step to implement dynamic object literal keys (see jashkenas#3597). This also fixes jashkenas#1392. In short, `super` is now allowed: # in class definitions: class A instanceMethod: -> super @staticmethod: -> super @staticMethod2 = -> super # in assignment where the next to last access is 'prototype': A::m = -> super A.prototype.m = -> super a.b()[5]::m = -> super A::[x()] = -> super class B @::m = -> super
As discussed in jashkenas#3039 (comment). This is the first step to implement dynamic object literal keys (see jashkenas#3597). This also fixes jashkenas#1392. In short, `super` is now allowed: # in class definitions: class A instanceMethod: -> super @staticmethod: -> super @staticMethod2 = -> super # in assignment where the next to last access is 'prototype': A::m = -> super A.prototype.m = -> super a.b()[5]::m = -> super A::[x()] = -> super class B @::m = -> super
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.
Is probably the best syntax. In an alternate universe, something like:
... might be preferable, but that ship has sailed. |
The following is now allowed: o = a: 1 b: 2 "#{'c'}": 3 "#{'d'}": 4 e: 5 "#{'f'}": 6 g: 7 It compiles to: o = ( obj = { a: 1, b: 2 }, obj["" + 'c'] = 3, obj["" + 'd'] = 4, obj.e = 5, obj["" + 'f'] = 6, obj.g = 7, obj ); - Closes jashkenas#3039. Empty interpolations in object keys are now _supposed_ to be allowed. - Closes jashkenas#1131. No need to improve error messages for attempted key interpolation anymore. - Implementing this required fixing the following bug: ("" + a): 1 The above used to error out on the colon, saying "unexpected colon". But really, it is the attempted object key that is unexpected. Now the error is on the opening parenthesis instead. - However, the above fix broke some error message tests for regexes. The easiest way to fix this was to make a seemingly unrelated change: The error messages for unexpected identifiers, numbers, strings and regexes now say for example 'unexpected string' instead of 'unexpected """some #{really long} string"""'. In other words, the tag _name_ is used instead of the tag _value_. This was way easier to implement, and is more helpful to the user. Using the tag value is good for operators, reserved words and the like, but not for tokens which can contain any text. For example, 'unexpected identifier' is better than 'unexpected expected' (if a variable called 'expected' was used erraneously). - While writing tests for the above point I found a few minor bugs with string locations which have been fixed.
The following is now allowed: o = a: 1 b: 2 "#{'c'}": 3 "#{'d'}": 4 e: 5 "#{'f'}": 6 g: 7 It compiles to: o = ( obj = { a: 1, b: 2 }, obj["" + 'c'] = 3, obj["" + 'd'] = 4, obj.e = 5, obj["" + 'f'] = 6, obj.g = 7, obj ); - Closes jashkenas#3039. Empty interpolations in object keys are now _supposed_ to be allowed. - Closes jashkenas#1131. No need to improve error messages for attempted key interpolation anymore. - Implementing this required fixing the following bug: ("" + a): 1 The above used to error out on the colon, saying "unexpected colon". But really, it is the attempted object key that is unexpected. Now the error is on the opening parenthesis instead. - However, the above fix broke some error message tests for regexes. The easiest way to fix this was to make a seemingly unrelated change: The error messages for unexpected identifiers, numbers, strings and regexes now say for example 'unexpected string' instead of 'unexpected """some #{really long} string"""'. In other words, the tag _name_ is used instead of the tag _value_. This was way easier to implement, and is more helpful to the user. Using the tag value is good for operators, reserved words and the like, but not for tokens which can contain any text. For example, 'unexpected identifier' is better than 'unexpected expected' (if a variable called 'expected' was used erraneously). - While writing tests for the above point I found a few minor bugs with string locations which have been fixed.
The following is now allowed: o = a: 1 b: 2 "#{'c'}": 3 "#{'d'}": 4 e: 5 "#{'f'}": 6 g: 7 It compiles to: o = ( obj = { a: 1, b: 2 }, obj["" + 'c'] = 3, obj["" + 'd'] = 4, obj.e = 5, obj["" + 'f'] = 6, obj.g = 7, obj ); - Closes jashkenas#3039. Empty interpolations in object keys are now _supposed_ to be allowed. - Closes jashkenas#1131. No need to improve error messages for attempted key interpolation anymore. - Implementing this required fixing the following bug: `("" + a): 1` used to error out on the colon, saying "unexpected colon". But really, it is the attempted object key that is unexpected. Now the error is on the opening parenthesis instead. - However, the above fix broke some error message tests for regexes. The easiest way to fix this was to make a seemingly unrelated change: The error messages for unexpected identifiers, numbers, strings and regexes now say for example 'unexpected string' instead of 'unexpected """some #{really long} string"""'. In other words, the tag _name_ is used instead of the tag _value_. This was way easier to implement, and is more helpful to the user. Using the tag value is good for operators, reserved words and the like, but not for tokens which can contain any text. For example, 'unexpected identifier' is better than 'unexpected expected' (if a variable called 'expected' was used erraneously). - While writing tests for the above point I found a few minor bugs with string locations which have been fixed.
I vote for
If string interpolation is needed, it can still be used like this Optionally the |
Yes, if we're adding new syntax in addition to interpolation it should definitely be
|
@lydell Oh I'm sorry, I didn't notice, that the |
Fix #3597: Allow interpolations in object keys
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.
The text was updated successfully, but these errors were encountered: