Constructing objects from named identifiers
The proposal of mine referenced by John in his link is obsolete, and has been replaced by rtm/js-pick-notation, with a new minimal variation at rtm/js-pick-notation/blob/master/minimal/spec.md which precisely leverages the current syntax and semantics of deconstructing.
John's proposal for picking into an anonymous object:
({p1, p2}) = o
overloads parentheses in a strange way, and is too easily confused with
({p1, p2} = o)
which means a completely different thing, and furthermore violates the semantics of the assignment operator, which is that it evaluates to the RHS, whereas he presumably intended this to evaluate to the newly created object.
The assignment operator =
makes sense in current deconstructing
assignments, since it is an assignment. It makes no sense in the context
of picking properties into objects.
In my proposal, this is
o.{p1, p2}
which has a clear analogy to the "single property picking" syntax o.p1
,
is syntactically unambiguous, easily parsable using existing machinery for
parsing deconstructors, and by virtue of re-using current deconstruction
syntax allows for renaming and defaults out of the box.
I've approached a couple of possible champions for this but no dice so far.
-- Bob
I don't see a need at all for that, since anyway you often need other manipulations, so if you need a functional way you can do:
let foo = ({a,b})=>({a:a+1, b:b+2})
then use foo, so the picking happens in function arguments
or if you need to, you use destructuring declaratively:
let {a, b} = o1
or ({a,b} = o1)
when reassigning a and b
OK, so from now on instead of o.p
I will write
(({p}) => p)(o)
Your second example misses the whole point. I do not want to deconstruct into variables (and then laboriously reconstruct an object from those variables). The entire notion is to deconstruct into objects.
I do not say this is "necessary", any more than padStart
is necessary. I
say it's a convenient, compact way to extend dot notation to allow
extracting multiple properties into a new object. In your first example you
have repeated a
and b
not twice, but three times, and your entire code,
even if rewritten as ({a,b})=>({a, b})(o)
, is 20 characters, instead of
the seven in o.{a,b}
, and much less readable. {a: o.a, b: o.b}
is
sixteen, and also repeats a
and b
twice.
The meta question is what criteria we want to apply to proposed syntax
additions or extensions which boil down to syntactic sugar. We could say we
don't need no stinkin' sugar, and the only changes we will consider are
those that provide new functionality not implementable in user code. But
there is already plenty of precedent for sugar-level additions to the
language. So the criteria becomes to what extent does the sugar allow us to
write more semantic, compact, readable, and less bug-prone code. IMHO
o.{a,b}
does qualify, opinions may differ.
Bob
On Fri, Jun 3, 2016 at 1:04 AM, Cyril Auburtin <cyril.auburtin at gmail.com>
wrote:
Reading a previous proposal rtm.github.io/boberator.html for a pick operator illuminated an obvious shortcoming in ES6's deconstructor syntax:
I see the problem:
let { p1, p2 } = o; let pickedProps = { p1, p2 };
Just take a leaf from Perl's book (page 59 to be absolutely precise):
let pickedProps{ p1, p2 } = o;
Anonymous/unnamed values could be yielded by using brackets:
({ p1, p2 }) = o; console.log("Value:", ({ p1, p2 }) = o);
Properties could be written to existing objects if they're named outside a
let/const/var
declaration:let pickedProps = {p1: "Old"}; pickedProps{ p1 } = o;
I wouldn't want the syntax to get too fancy, but if anybody feels like property renaming should be supported, I guess it could be achieved like this (I prefer the first):
let pickedProps{ p1 as One, p2 as Two } = o; // ... or even: let pickedProps{ p1:One, p2:Two } = o;
Yes, the
as
keyword is used for importing modules, but since modules are parsed statically prior to evaluation, I can't see this causing an issue.Thoughts?