Reified lvalue (was: Re: Extensible destructuring proposal)
# Isiah Meadows (9 years ago)
I know this is pointless bikeshedding, but that particular operator conflicts with a current valid production.
// These are synonymous, and are
// valid statements
tmp0 <- input.get('c')
tmp0 < (-input.get('c'))
I know this is pointless bikeshedding, but that particular operator conflicts with a current valid production. ```js // These are synonymous, and are // valid statements tmp0 <- input.get('c') tmp0 < (-input.get('c')) ``` On Wed, Aug 19, 2015, 09:53 Herby Vojčík <herby at mailbox.sk> wrote: > > > Bergi wrote: > > Samuel Hapák schrieb: > > > >> The main idea is, that if object defines `Symbol.get` method, it gets > >> used to access properties of object instead of `[]` when destructuring. > > > > Aw, when I read "extensible destructuring" I had hoped to see an > > extension to the destructuring syntax, not to see how semantics of > > destructuring objects are changed. > > > > What do you think about extractor functions, like in Scala > > <http://www.scala-lang.org/old/node/112>? > > Instead of `unapply` or `unapplySeq` methods we'd probably use an > > `@@extractor` (`Symbol.extractor`) method or so, allowing us to do > > > > let Map({a, b, c}) = myMap; > > > > let List(a, b, c) = myList; > > > > const Map({author: Map({name: {first, last}, birthdate})}) = book; > > > > which would desugar to > > > > let [{a, b, c}] = Map[Symbol.extractor](myMap); > > > > let [a, b, c] = List[Symbol.extractor](myList); > > > > const [{author: __author}] = Map[Symbol.extractor](book); > > const [{name: {first, last}, birthdate}] = > Map[Symbol.extractor](__author); > > > > where each extractor method would return an Iterable that is assigned to > > the "arguments" of the extractor. (A Proxy to lazily destructure object > > literals in there is a good idea, thanks @Claude). > > > > This would even allow us to call functions on destructuring, think about > > module imports: > > > > // a.js > > export default function factory(options) { > > … > > return moduleInstance; > > } > > > > // b.js > > const NoOptions = { > > [Symbol.extractor](factory) { return [factory()]; } > > }; > > const WithOptions = (...args) => ({ > > [Symbol.extractor](factory) { return [factory(...args)]; } > > }); > > > > import NoOptions(A) from "a"; > > import WithOptions("config")(A) from "a"; > > // A === moduleInstance > > > > What do you think about that? > > Nice, but as Samuel mentioned, you need to actually transform the data > so it can be fed to stock destructurer. > > What I came up is the idea of "reified lvalue", the object that > describes the (complex, destucturing) lvalue used for assignment (for > example as the list of simple expression assignments, internally); and > that such object could be transformed. > > Like (very rough examples; just an idea, not the spec): > > let a = 4; > > outer a <- input > > > let {a,c:{b}} = foo; > > outer a <- input.a > tmp0 <- input.c > outer b <- tmp0.b > > > let {a,c:Map({b})} = foo; > > Map[Symbol.lvalue] gets "outer b <- input.b" and transforms it to > "outer b <- input.get('b')", so the result would be: > > outer a <- input.a > tmp0 <- input.c > outer b <- tmp0.get('b') > > > let Map(a,c:Map({b})) = foo; > > Map[Symbol.lvalue] get the above descriptor and transforms it to > > outer a <- input.get('a') > tmp0 <- input.get('c') > outer b <- tmp.get('b') > > If things like Map[Symbol.lvalue] would be frozen (or just speculatively > supposed not to be mutated), this can as well be done at compile time, > so the resulting code could stay fast. > > > Bergi > > Herby > _______________________________________________ > 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/20150820/104cde8f/attachment.html>
# Isiah Meadows (9 years ago)
No problem. I was aware of the intent. Also, I cc'd the list for you.
P.S. I did state it as pointless bikeshedding, so I did kinda leave myself open for criticism for merely bringing it up.
No problem. I was aware of the intent. Also, I cc'd the list for you. P.S. I did state it as pointless bikeshedding, so I did kinda leave myself open for criticism for merely bringing it up. On Thu, Aug 20, 2015, 02:08 Herby Vojčík <herby at mailbox.sk> wrote: > > > Isiah Meadows wrote: > > I know this is pointless bikeshedding, but that particular operator > > conflicts with a current valid production. > > > > ```js > > // These are synonymous, and are > > // valid statements > > tmp0 <- input.get('c') > > tmp0 < (-input.get('c')) > > ``` > > This was symbolic way of write the series of assignments, not a JS code > (so "```js" does not make sense here). The idea was they would anyway be > encoded somehow differently. > Sorry if this was not understood. > > > > > > > On Wed, Aug 19, 2015, 09:53 Herby Vojčík <herby at mailbox.sk > > <mailto:herby at mailbox.sk>> wrote: > > > > > > > > Bergi wrote: > > > Samuel Hapák schrieb: > > > > > >> The main idea is, that if object defines `Symbol.get` method, > > it gets > > >> used to access properties of object instead of `[]` when > > destructuring. > > > > > > Aw, when I read "extensible destructuring" I had hoped to see an > > > extension to the destructuring syntax, not to see how semantics of > > > destructurin > g objects are changed. > > > > > > What do you think about extractor functions, like in Scala > > > <http://www.scala-lang.org/old/node/112>? > > > Instead of `unapply` or `unapplySeq` methods we'd probably use an > > > `@@extractor` (`Symbol.extractor`) method or so, allowing us to do > > > > > > let Map({a, b, c}) = myMap; > > > > > > let List(a, b, c) = myList; > > > > > > const Map({author: Map({name: {first, last}, birthdate})}) = book; > > > > > > which would desugar to > > > > > > let [{a, b, c}] = Map[Symbol.extractor](myMap); > > > > > > let [a, b, c] = List[Symbol.extractor](myList); > > > > > > const [{author: __author}] = Map[Symbol.extractor](book); > > > const [{name: {first, last}, birthdate}] = > > Map[Symbol.extractor](__author); > > > > > > where each extractor method would return an Iterable that is > > assigned to > > > the "arguments" of the extractor. (A Proxy to lazily destructure > > object > > > li > terals in there is a good idea, thanks @Claude). > > > > > > This would even allow us to call functions on destructuring, > > think about > > > module imports: > > > > > > // a.js > > > export default function factory(options) { > > > … > > > return moduleInstance; > > > } > > > > > > // b.js > > > const NoOptions = { > > > [Symbol.extractor](factory) { return [factory()]; } > > > }; > > > const WithOptions = (...args) => ({ > > > [Symbol.extractor](factory) { return [factory(...args)]; } > > > }); > > > > > > import NoOptions(A) from "a"; > > > import WithOptions("config")(A) from "a"; > > > // A === moduleInstance > > > > > > What do you think about that? > > > > Nice, but as Samuel mentioned, you need to actually transform the > data > > so it can be fed to stock destructurer. > > > > What I came up is the idea of "reified lvalue", the object that > > describes the (complex, destucturing) lvalue used for assignment (for > > > example as the list of simple expression assignments, internally); and > > that such object could be transformed. > > > > Like (very rough examples; just an idea, not the spec): > > > > let a = 4; > > > > outer a <- input > > > > > > let {a,c:{b}} = foo; > > > > outer a <- input.a > > tmp0 <- input.c > > outer b <- tmp0.b > > > > > > let {a,c:Map({b})} = foo; > > > > Map[Symbol.lvalue] gets "outer b <- input.b" and transforms it to > > "outer b <- input.get('b')", so the result would be: > > > > outer a <- input.a > > tmp0 <- input.c > > outer b <- tmp0.get('b') > > > > > > let Map(a,c:Map({b})) = foo; > > > > Map[Symbol.lvalue] get the above descriptor and transforms it to > > > > outer a <- input.get('a') > > tmp0 <- input.get('c') > > outer b <- tmp.get('b') > > > > If things like Map[Symbol.lvalue] would be frozen (or just > > speculatively > > supposed not to be mutated), this can as well be done at compi > le time, > > so the resulting code could stay fast. > > > > > Bergi > > > > Herby > > _______________________________________________ > > es-discuss mailing list > > es-discuss at mozilla.org <mailto: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/20150822/2c3db5ee/attachment-0001.html>
Bergi wrote:
Nice, but as Samuel mentioned, you need to actually transform the data so it can be fed to stock destructurer.
What I came up is the idea of "reified lvalue", the object that describes the (complex, destucturing) lvalue used for assignment (for example as the list of simple expression assignments, internally); and that such object could be transformed.
Like (very rough examples; just an idea, not the spec):
let a = 4;
outer a <- input
let {a,c:{b}} = foo;
outer a <- input.a tmp0 <- input.c outer b <- tmp0.b
let {a,c:Map({b})} = foo;
Map[Symbol.lvalue] gets "outer b <- input.b" and transforms it to "outer b <- input.get('b')", so the result would be:
outer a <- input.a tmp0 <- input.c outer b <- tmp0.get('b')
let Map(a,c:Map({b})) = foo;
Map[Symbol.lvalue] get the above descriptor and transforms it to
outer a <- input.get('a') tmp0 <- input.get('c') outer b <- tmp.get('b')
If things like Map[Symbol.lvalue] would be frozen (or just speculatively supposed not to be mutated), this can as well be done at compile time, so the resulting code could stay fast.