-
Notifications
You must be signed in to change notification settings - Fork 2k
Default values for destructuring parameters #1558
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
Comments
Is this a silly request? |
Not at all. It's certainly consistent. I think it may be a little "too much", but I can't really define that term. At the very least, you've notified us that destructuring parameter lists are undocumented. |
thanks. I guess what I'm trying to say is: Sometimes we end up adding many new parameters to functions, when they should probably be promoted to named parameter lists (ever seen a function that takes 5+ unnamed arguments??). Some people may hold off on making the switch to named parameters if they have to sacrifice the succinctness of being able to supply default params within the function signature. Though in saying that, it's not going to look so succinct unless the parameter list can be specified over multiple lines, in which we'd have to agree on some new syntax which doesn't look gross, and in that case perhaps handwriting defaults for parameter lists isn't really so bad afterall. :/ |
which it can be |
whoa, how did I miss that? It can too, just isn't picked up by the textmate syntax highlighter, and is a bit bracey, well… my bad. |
Given that, I'm back on the 'ability to provide defaults would be good' bandwagon. |
I almost forgot: the main proposal in this issue is very closely related to #1162 (which expresses my above-referenced complexity concerns pretty well) and #810. I want to make sure we don't forget about documenting destructuring parameters if we decide to close this, so can you open a separate issue for that? |
Separate issue created for undocumented destructuring parameters I'd agree with the conclusion in other thread, all of the proposed solutions in that other thread are ridiculous and complex, this is coffeescript, not regex/perl. The idea here is to keep the simple syntax and functionality consistent between named and unnamed params. I'd argue that this proposal in fact reduces complexity; you have a single syntax with the same rules for both approaches to parameters. Perhaps there are aspects that complicate things I am not aware of though. |
+1 It's a commonly used pattern and having default values will make it much sweeter than writing your own mixin function. |
So how should that compile? Would it allow nesting? Would it work elsewhere then in function declarations? If not, then what about consistency? |
Hacky workaround that currently works: constructor: ({name, description}, description = "not described") -> |
@codelahoma: that code is discouraged. See #1002, #1547. Identical parameter names will be a syntax error soon. |
+1 |
Please don't bump after a year. I remember this syntax worked great in Coffee 1.3 but got broken/removed in Coffee 1.4 |
@Nami-Doc Is there a better bug to poke? I started using CoffeeScript pretty recently so I don’t know what was different in CoffeeScript 1.3. I noticed that this works: (foo = bar, { baz }) -> …this doesn’t: (foo, { baz = bar }) -> …and it seems to match what the OP brought up. |
I remember an issue bringing this regression up but I wasn't able to find it back. Will look again later |
+1 for default values working in object destructuring. I expect: f = ({name = "Fred"}) ->
console.log name
# to be equivalent to
f = (args) ->
{name = "Fred"} = args
console.log "Fred"
# and equivalent to
f = ({name}) ->
name ?= "Fred"
console.log name This essentially gives CoffeeScript "proper" keyword arguments: function parameters that can be invoked by name in any order, and may be left out to use a default instead. (Okay, technically the middle version isn't 100% equivalent because it also leaves a variable called |
+1 On Wed, Feb 13, 2013 at 8:31 PM, 00Davo [email protected] wrote:
|
On testing out the behaviour of that third snippet: f = ({name}) ->
name ?= "Fred"
console.log name I find it works perfectly if you call |
Mmm... i'd prefer they didn't. As of now, argument destructuring is only a handy shortcut to say "i don't care about this n-th parameter as a whole object, i just care about these properties". The specific properties can be undefined, but not the object itself. You can make the call work without any arguments by specifying a default value for that parameter, just like any other parameter: f = ({name} = {}) ->
name ?= "Fred"
console.log name You can even do: defaults =
name: 'Fred'
f = ({name} = defaults) ->
console.log name I'm partially in favour of this proposal though. Being able to specify default values for destructuring arguments seems pretty handy. I'm pretty sure though that this same topic has been discussed here before; and that the discussion turned out lengthy and dragging (thanks in part to me xD). |
Ah, Object destructuring still would be much better with defaults, though. |
I found the old discussion. It's lengthy, but i just wanted to make a reference not to repeat myself (too much 😝 ). I'm glad we're on the same boat about object-destructuring parameters not implicitly defaulting to an empty object, @00Davo 😃 Digging through the issues i also found that @jashkenas was not in favour of having destructuring parameters and complicated parameter list expressions (#362). I wonder why have his opinion changed though (if it actually has changed); seeing some recent issues about parameter lists being confused with other expressions, i kinda wish the decision to keep parameter expression as simple identifiers would've held. |
Me too. |
I completely disagree. A parameter list its just an implicit positional destructuring assignment of |
According to this blog post I just stumbled upon, ES6 is going to have defaults in destructuring (look for the heading called "Default Values"):
From the CoffeeScript documentation:
According to the same blog post:
If that blog post is right, I'd say: Nobody cares about that old Harmony proposal anymore: Update the docs! Either say that CoffeeScript destructuring is like ES6 destructuring, except that defaults are not possible, since they are considered too complex or something (just like loose comparison via JS's |
+1 on mimicking destructuring defaults from ES6. They're hardly a "considered harmful" feature that CoffeeScript should inhibit use of, like |
Note that ES6 destructuring defaults isn't just about function parameters—it works anywhere. For example, this jQuery.ajax = function (url, {
async = true,
beforeSend = function () {},
cache = true,
complete = function () {},
crossDomain = false,
global = true,
// ... more config
}) {
// ... do stuff
}; could be replaced with jQuery.ajax = function (url, options) {
var {
async = true,
beforeSend = function () {},
cache = true,
complete = function () {},
crossDomain = false,
global = true,
// ... more config
} = options
// ... do stuff
}; if that's considered more readable. This issue is called "Default values for destructuring parameters", while what I propose would be simply "Default values for destructuring". |
Yep, CoffeeScript's destructuring should be consistent between parameter lists and regular assignments, especially given that ES6's works in both contexts. Mirroring the ES6 support for default values in all destructuring patterns seems a good move. |
I currently use fn = ({foo, bar} = {foo: 3}) -> and definitely would prefer fn = ({foo = 3, bar}) -> Note that for the second to be equivalent, I must be able to call |
This let's you do things like: fullName = ({first = 'John', last = 'Doe'}) -> "#{first} #{last}" Note: CoffeeScrits treats `undefined` and `null` the same, and that's true in the case of destructuring defaults as well, as opposed to ES2015 which only uses the default value if the target is `undefined`. A similar ES2015 difference already exists for function parameter defaults. It is important for CoffeeScript to be consistent with itself. fullName2 = (first = 'John', last = 'Doe') -> "#{first} #{last}" assert fullName('Bob', null) is fullName2(first: 'Bob', last: null) Fixes jashkenas#1558, jashkenas#3288 and jashkenas#4005. A test that lone expansions `[...]=a` are prohibited failed with this commit. However, the error message used to be really weird and shows that the test just _happened_ to pass: $ coffee -bpe '[...]=a' [stdin]:1:2: error: Expansion must be used inside a destructuring assignment or parameter list [...]=a ^^^ That _is_ inside a destructuring assignment. Since `[]=a` is allowed, I figured the easiest and most consistent way would be to make `[...]=a` equivalent to `[]=a`.
This let's you do things like: fullName = ({first = 'John', last = 'Doe'}) -> "#{first} #{last}" Note: CoffeeScrits treats `undefined` and `null` the same, and that's true in the case of destructuring defaults as well, as opposed to ES2015 which only uses the default value if the target is `undefined`. A similar ES2015 difference already exists for function parameter defaults. It is important for CoffeeScript to be consistent with itself. fullName2 = (first = 'John', last = 'Doe') -> "#{first} #{last}" assert fullName('Bob', null) is fullName2(first: 'Bob', last: null) Fixes jashkenas#1558, jashkenas#3288 and jashkenas#4005. A test that lone expansions `[...]=a` are prohibited failed with this commit. However, the error message used to be really weird and shows that the test just _happened_ to pass: $ coffee -bpe '[...]=a' [stdin]:1:2: error: Expansion must be used inside a destructuring assignment or parameter list [...]=a ^^^ That _is_ inside a destructuring assignment. Since `[]=a` is allowed, I figured the easiest and most consistent way would be to make `[...]=a` equivalent to `[]=a`.
This let's you do things like: fullName = ({first = 'John', last = 'Doe'}) -> "#{first} #{last}" Note: CoffeeScrits treats `undefined` and `null` the same, and that's true in the case of destructuring defaults as well, as opposed to ES2015 which only uses the default value if the target is `undefined`. A similar ES2015 difference already exists for function parameter defaults. It is important for CoffeeScript to be consistent with itself. fullName2 = (first = 'John', last = 'Doe') -> "#{first} #{last}" assert fullName('Bob', null) is fullName2(first: 'Bob', last: null) Fixes jashkenas#1558, jashkenas#3288 and jashkenas#4005.
This let's you do things like: fullName = ({first = 'John', last = 'Doe'}) -> "#{first} #{last}" Note: CoffeeScrits treats `undefined` and `null` the same, and that's true in the case of destructuring defaults as well, as opposed to ES2015 which only uses the default value if the target is `undefined`. A similar ES2015 difference already exists for function parameter defaults. It is important for CoffeeScript to be consistent with itself. fullName2 = (first = 'John', last = 'Doe') -> "#{first} #{last}" assert fullName('Bob', null) is fullName2(first: 'Bob', last: null) Fixes jashkenas#1558, jashkenas#3288 and jashkenas#4005.
This let's you do things like: fullName = ({first = 'John', last = 'Doe'}) -> "#{first} #{last}" Note: CoffeeScrits treats `undefined` and `null` the same, and that's true in the case of destructuring defaults as well, as opposed to ES2015 which only uses the default value if the target is `undefined`. A similar ES2015 difference already exists for function parameter defaults. It is important for CoffeeScript to be consistent with itself. fullName2 = (first = 'John', last = 'Doe') -> "#{first} #{last}" assert fullName('Bob', null) is fullName2(first: 'Bob', last: null) Fixes jashkenas#1558, jashkenas#3288 and jashkenas#4005.
What I'm proposing is the ability to supply default values for parameter lists (note the {}):
I was surprised when this didn't compile, considering you can set defaults for regular named arguments, and also destructuring arguments (i.e. all types of named arguments except parameter lists).
It'd also be nice to be able to describe parameter lists over multiple lines, but I couldn't think of a way to do it without making it rather ({ugly}), eg:
edit: the above actually works.
Additionally, the destructuring parameter lists syntax isn't mentioned in the docs anywhere, and the syntax is really neat:
edit: rewritten to use the term 'destructuring parameter lists' instead of 'unknown auto-assigned option things huh?'.
edit 2: clarified the ticket, as I didn't actually understand what I had written myself.
The text was updated successfully, but these errors were encountered: