-
Notifications
You must be signed in to change notification settings - Fork 2k
Proposal: Syntactic sugar: Sub-structuring #4991
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
Just following up on the thought process... If we fully implement sub-structuring, following should also work: user{title, name:full_name} = data
# >> ({title: user.title, name: user.full_name} = data);
user{addr:{street:[street1, street2], city, state, zip} } = data
# >> ({addr:{street:[user.street1, user.street2], city:user.city, state:user.state, zip:user.zip} } = data);
book = data{title, authors:[{name:author},{name:coauthor=null}]}
# >> book = ({title:_title, authors:[{name:_name1},{name:_name2=null}]} = data, {title:_title, author:_name1, coauthor:_name2}); We can optionally support rest/spread syntax, with an easily understandable way to subtract unwanted props: user{name, birthdate, -password, ...extra_info} = data
# >> ({name: user.name, password:_blackhole, ...user.extra_info} = data);
record = data{id, -unwanted, ...properties}
# >> record = ({id:_id, unwanted:_blackhole, ..._properties} = data, {id:_id, properties: _properties}); Sub-structuring doesn't have to used in an assignment: console.log data{id, -unwanted, ...properties}
# >> console.log({id:_id, unwanted:_blackhole, ..._properties} = data, {id:_id, properties: _properties}); "Re-structuring" (another made up term, super nice to have, but possibly overkill): users.push data{id, name:fullname, {[str1, str2]:=street, city, state, zip:postal}:=address}
# >> users.push((
# >> {id:_id, name:_name, str1:_str1, str2:_str2, city:_city, state:_state, zip:_zip} = data,
# >> {id:_id, fullname:_name, address: {street:[_str1, _str2], city:_city, state:_state, postal:_zip }}
# >> ));
data{a, {b:{c, [x,y]:=z}}:=d}
# >> ({a:_a, b:{c:_c, x:_x, y:_y}} = data, {a:_a, d:{c:_c, z:[_x, _y]}}); |
Can you please explain this with more detailed examples? user = undefined
data =
title: 'Mr'
surname: 'Coffee'
user{ title, name: surname } = data What does |
Sorry if I missed a few things in the descriptions. In your example the point would be to set We could also add a compile-time check similar to the current error thrown if you write |
@aminland I'm working on a PR for this and I want to check if I'm on the right track. data =
title: "Mr"
name: "Coffee"
address: "Sesame Street"
view = data{title, name:full_name}
# view = { title: "Mr", full_name: "Coffee" }
view = data{title, name:full_name, rest...}
###
view = {
title: "Mr",
full_name: "Coffee",
rest: {
address: "Sesame Street"
}
}
###
console.log data{title, name:full_name}
# { title: "Mr", full_name: "Coffee" } data =
title: "Mr"
name: "Coffee"
address: "Sesame Street"
view{title, name:full_name} = data
###
error: the variable 'view' has not been declared before
view{title, name:full_name} = data
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
### data =
title: "Mr"
name: "Coffee"
address: "Sesame Street"
view = address: "Elm Street"
view{title, name:full_name} = data
###
view = { address: 'Elm Street', title: 'Mr', full_name: 'Coffee' }
###
|
I am all for this 👍 Especially the rhs substructuring which would make it possible to neatly deal with data in an immutable/declarative way and eliminate many an intermediate variable when wrangling objects between interfaces. I'm less sure about the { a, -b, c... } = d Syntax-wise I'm not sure if I prefer |
Just a quick update on the progress. data =
title: "Mr"
name: "Coffee"
address: "Sesame Street"
zip: 10001
view = city: "London"
view{title, name, -zip, rest...} = data
# view = {city: "London", title: "Mr", name: "Coffee", rest: {address: "Sesame Street"}} @connec your example also compiles. d = {a, b, x, y}
{a, -b, c...} = d
###
a = a
c = {x, y}
### I have to clean up the code a little bit and then I'll create a PR. |
Sorry to dampen the mood, folks, but we should not implement this feature. Being whitespace sensitive to this degree is confusing, and more harmful than the feature is beneficial. As you all know quite well:
Expands into:
If
Became something entirely different, that would be a big step backwards in readability for CoffeeScript. |
@jashkenas but we already have this type of sensitivity for whitespace: The whole greatness of CoffeeScript stems exactly from this whitespace sensitivity, no? |
And it's not ideal there either! |
We have the sensitivity everywhere. |
Alright, then, I'm overruled. If y'all are all for it, then go for it! |
Could make them both require point.{x, y}
point.[x] |
Please no breaking changes 😭 I had suggested point{x} for consistency with array access and array assignment (and also i figured it would be easier to parse the grammar for it, since you wouldn't have to special case the existing |
The distinction between As well, why would using the dot (as in Reserving the proposed grammar just seems prudent, and |
I’m worried about getting ahead of the ECMA committee on this. We dodged a bullet in that the meaning of ES2015 destructuring syntax was essentially identical to how we had defined it, thanks in no small part to the fact that we had pioneered it, of course. But we weren’t so lucky when it came to other things like how they redefined function default values, which led to one of the CS2 breaking changes. If we incorporate this feature and declare that this syntax means this functionality, what happens if or when ECMA decides to use this syntax for something else? Or for predominantly the same thing, but with differences? I understand that the logical conclusion of my argument means that CoffeeScript cedes its role as a contributor of innovation in JavaScript. That saddens me, and I’d like to avoid it if we can find a way to thread this needle. But JavaScript is not moribund anymore, like it was in the days when CoffeeScript flourished. There is a process for proposing new JavaScript features and getting them accepted: the TC39 committee. Perhaps this should be proposed there, as a potential new syntax and feature for JavaScript. If it reaches Stage 3, we can merge this PR (with its polyfill implementation) into CoffeeScript. When the syntax reaches Stage 4, we can refactor this so that CoffeeScript outputs the syntax “as is.” By working with the committee, we’ll ensure that whatever ends up incorporated into JavaScript doesn’t cause breaking changes in CoffeeScript, and we’ll improve JavaScript too. |
note that this is already possible (sort of) like this: -> {a: @aa, @rest...} = obj2
.call obj1 |
Why not |
Closing per #4991 (comment). |
There appears to be a similar proposal under discussion on esdiscuss: https://esdiscuss.org/topic/extended-dot-notation-pick-notation-proposal I wouldn't be surprised if some proposal for picking elements from objects doesn't advance soon. |
Note that some prior discussion on this was started in #4919, before that thread turned into a discussion on something unrelated.
Right now, destructuring is only supported as a means to assign properties to vars in top level scope.
The proposal is for a new syntax to support assigning properties from one object into another object (i.e. building / extending objects). I've borrowed the term "substructuring" from livescript.
The proposed sugar would behave as follows (js output shown):
I think this would make a lot of things simpler in coffeescript, as the syntax is much more concise. The important thing to note here is that there must not be a whitespace between the source object and the
{
symbol, allowing easy differentiation between this syntax and a function call.Thoughts?
The text was updated successfully, but these errors were encountered: