Proposal: syntactic sugar for extracting fields from objects

Jacob Pratt jhprattdev at gmail.com
Sun Jun 30 07:01:36 UTC 2019


Is there any interest from a TC39 member with regards to a possible pick
notation or `Object.pick` method? It's been something proposed a few times
over, typically using similar syntax, and seems to have broad support.

At the very least, couldn't this become a stage 0 proposal? Bob has already
created a [repository], and the [process document] specifies no entrance
criteria for stage 0. If a champion were identified, stage 1 doesn't seem
far off.

[repository]: https://github.com/rtm/js-pick-notation
[process document]: https://tc39.es/process-document/

Jacob Pratt


On Wed, Jun 5, 2019 at 5:59 AM Isiah Meadows <isiahmeadows at gmail.com> wrote:

> Nit: 2A will reject thanks to TDZ semantics with `name` in the RHS
> where it's defined in the LHS of the same statement. (Think of the
> function body's lexical context as being in a block where parameters
> are in a parent block context. The block variable shadows the parent
> variable for the whole block and just initially starts as unset.) So
> that error *will* get caught fairly quickly.
>
> But aside from that:
>
> I agree 1A is a bit too noisy, especially in the parameter side.
>
> 1B could be simplified a bit. Have you considered leveraging the
> existing object rest+spread and just standard property accesses? This
> is technically shorter than your suggestion and is much less
> cluttered. (I do see a frequent pattern of premature destructuring
> when it's shorter, easier, and simpler *not* to.)
>
> ```
> return {...state.user.{firstName, lastName}, url:
> state.common.currentPageURL}
> ```
>
> 2A could be fixed to work like this, which is technically shorter than
> your example:
>
> ```
> const resp = await sendToServer({name})
> return {ok: true, payload: {name: resp.name}}
> ```
>
> And likewise, you could simplify 2B to this:
>
> ```
> const resp = await sendToServer({name})
> return {ok: true, payload: resp.{name}}
> ```
>
> -----
>
> Isiah Meadows
> contact at isiahmeadows.com
> www.isiahmeadows.com
>
> On Tue, May 28, 2019 at 3:13 PM Григорий Карелин <grundiss at gmail.com>
> wrote:
> >
> > Here are another examples, where "destructuring picking" I suggest
> whould be helpful.
> > ==1A Now (redux related)
> > ```
> > function mapStateToProps({user: {firstName, lastName}, common:
> {currentPageURL: url}}) {
> >   return {firstName, lastName, url};
> > }
> > ```
> > ==1B Proposal
> > ```
> > function mapStateToProps(state) {
> >   return {{firstName, lastName from state.user}, {currentPageURL as url
> from state.common}};
> > }
> > ```
> >
> > Shorter!
> >
> > ==2A Now
> > ```
> > async function saveNewUserName(name) {
> >   const {name} = await sendToServer({name});
> >
> >   return {ok: true, payload: {name}}; // oh wait, which name is it
> again? Argument or response?
> > }
> > ```
> > == 2B Proposal
> > ```
> > async function saveNewUserName(name) {
> >   const resp = await sendToServer({name});
> >
> >   return {ok: true, {name from response}};
> > }
> > ```
> > No accidental shadowing.
> >
> > I know, I know, you can achieve all that without new syntax, via naming
> your variables properly and using long explicit expressions. But I think
> some sugar won't hurt.
> > After all, remember destructuring? There's no reason to use it other
> than it's cool and short and expressive.
> >
> >
> > вт, 28 мая 2019 г. в 21:49, guest271314 <guest271314 at gmail.com>:
> >>>>
> >>>> ```
> >>>> let obj = {otherData: "other data"};
> >>>> ({firstName:obj.firstName, lastName:obj.lastName} = user.profile);
> >>>> ```
> >>>>
> >>>> I don't understand this.
> >>
> >>
> >>
> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Assigning_to_new_variable_names
> >>
> >>> He's looking for a terser
> >>
> >>
> >> Is the proposal to golf destructuring assignment?
> >>
> >> The proposed destructuring assignment syntax example is 25 characters
> less than the non-destructing assignment example, which is terser.
> >>
> >> One observation about the proposed syntax is that the values set at the
> target object would be set from the identifier on the left side of
> ```from``` which is similar to
> >>
> >> ```
> >> var o = {x:1};
> >> console.log(o.x = 2); // 2
> >> ```
> >>
> >> though how will the property name be set at the object at target object
> instead of `{"2":2}`? How does the engine know when the expected result is
> ```{"x":2}``` and not ```{"2":2}```? Certainly such functionality can be
> designed, for example, using the proposed key word ```from```.
> >>
> >> If more terse code is one of the features that would be achieved, why
> are the wrapping `{}` around ```from`` necessary?
> >>
> >> > moire elegant way to do it,
> >>
> >> "elegant" is subjective
> >>
> >> > which hopefully would be moire semantic, less bug-prone, more
> type-checkable (for typed variants of the language), more reminiscent of
> existing syntax such as deconstruction, and potentially more optimizable by
> engines.
> >>
> >> What is bug prone about the code examples at OP?
> >>
> >> This proposal would resolve the issue of currently, in general, having
> to write the property name twice.
> >>
> >>
> >>
> >> On Tue, May 28, 2019 at 2:47 PM Bob Myers <rtm at gol.com> wrote:
> >>>>
> >>>> ```
> >>>> let obj = {otherData: "other data"};
> >>>> ({firstName:obj.firstName, lastName:obj.lastName} = user.profile);
> >>>> ```
> >>>
> >>>
> >>> I don't understand this.
> >>>
> >>>>
> >>>> Alternatively there are various approaches which can be used to get
> only specific properties from an abject and set those properties and values
> at a new object without using destructing assignment.
> >>>>
> >>>> Using object rest and ```reduce()```
> >>>>
> >>>> ```let obj = {otherData: "other data", ...["firstName",
> "lastName"].reduce((o, prop) => (o[prop] = user.profile[prop], o), {})};```
> >>>>
> >>>> `Object.assign()`, spread syntax and `map()`
> >>>>
> >>>> ```let obj = Object.assign({otherData: "other data"},
> ...["firstName", "lastName"].map(prop => ({[prop]:user.profile[prop]})));```
> >>>
> >>>
> >>> As the words "syntactic sugar" in the subject of the thread make
> clear, the OP is not merely looking for ways to assign one object's
> property into another--there are many ways to do that. He's looking for a
> terser, moire elegant way to do it, which hopefully would be moire
> semantic, less bug-prone, more type-checkable (for typed variants of the
> language), more reminiscent of existing syntax such as deconstruction, and
> potentially more optimizable by engines.
> >>>
> >>> Bob
> >>> _______________________________________________
> >>> es-discuss mailing list
> >>> es-discuss at mozilla.org
> >>> https://mail.mozilla.org/listinfo/es-discuss
> >>
> >> _______________________________________________
> >> es-discuss mailing list
> >> es-discuss at mozilla.org
> >> https://mail.mozilla.org/listinfo/es-discuss
> >
> >
> >
> > --
> > С уважением,
> > Карелин Григорий
> > _______________________________________________
> > es-discuss mailing list
> > es-discuss at mozilla.org
> > https://mail.mozilla.org/listinfo/es-discuss
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20190630/f87aad1b/attachment.html>


More information about the es-discuss mailing list