Extensible destructuring proposal

classic Classic list List threaded Threaded
31 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Extensible destructuring proposal

Samuel Hapák
Hello there,

I have written proposal to allow extend standard behavior of object destructuring:
https://github.com/vacuumlabs/es-proposals/blob/master/extensible-destructuring.md

Main idea is, that currently object destructuring is useless for people who use Map or Immutable.Map (https://facebook.github.io/immutable-js/) as their main data structure.

This would allow authors of libraries to create map like structures that would support destructuring. It extends the language in a similar way iterator does.

The main idea is, that if object defines `Symbol.get` method, it gets used to access properties of object instead of `[]` when destructuring.

What do you think?

Cheers,

Samuel







_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

smime.p7s (4K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Extensible destructuring proposal

Andreas Rossberg-4
On 21 July 2015 at 08:14, Samuel Hapák <[hidden email]> wrote:
I have written proposal to allow extend standard behavior of object destructuring:
https://github.com/vacuumlabs/es-proposals/blob/master/extensible-destructuring.md

Main idea is, that currently object destructuring is useless for people who use Map or Immutable.Map (https://facebook.github.io/immutable-js/) as their main data structure.

This would allow authors of libraries to create map like structures that would support destructuring. It extends the language in a similar way iterator does.

The main idea is, that if object defines `Symbol.get` method, it gets used to access properties of object instead of `[]` when destructuring.

What do you think?

People reading code will (rightfully) expect destructuring to be syntactic sugar for property access. I don't think it's worth breaking that equivalence. If you want user-defined patterns then they should be syntactically distinct from existing forms.

Also, destructuring patterns are meant to match, and be the logical inverse of, literal syntax. Consequently, from my perspective at least, extensible destructuring would require first introducing extensible literal syntax in a symmetric manner. I think it would be unnecessarily surprising if for random patterns they didn't match up (worse, if you cannot even tell the meaning syntactically, but it depends on whatever object you happen to get).

/Andreas


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Extensible destructuring proposal

Claude Pache
In reply to this post by Samuel Hapák

> Le 21 juil. 2015 à 08:14, Samuel Hapák <[hidden email]> a écrit :
>
> Hello there,
>
> I have written proposal to allow extend standard behavior of object destructuring:
> https://github.com/vacuumlabs/es-proposals/blob/master/extensible-destructuring.md
>
> Main idea is, that currently object destructuring is useless for people who use Map or Immutable.Map (https://facebook.github.io/immutable-js/) as their main data structure.
>
> This would allow authors of libraries to create map like structures that would support destructuring. It extends the language in a similar way iterator does.
>
> The main idea is, that if object defines `Symbol.get` method, it gets used to access properties of object instead of `[]` when destructuring.
>
> What do you think?
>
> Cheers,
>
> Samuel
>

An alternative to `Symbol.get` is a Proxy with a "get" trap. Maybe worth experimenting with Proxies?

For example, one can imagine something like:

```js
    const {author: {name: {first, last}, birthdate}} = book.toObject()
```

where `.toObject()` is a method returning a proxy, or, in implementations lacking proxies, falling back to convert eagerly the structure into a plain object.

—Claude

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Extensible destructuring proposal

Samuel Hapák
In reply to this post by Andreas Rossberg-4

> On 21.7.2015, at 9:34, Andreas Rossberg <[hidden email]> wrote:
>
> People reading code will (rightfully) expect destructuring to be syntactic sugar for property access. I don't think it's worth breaking that equivalence. If you want user-defined patterns then they should be syntactically distinct from existing forms.

This is already not true for array destructuring. You can use it with any iterables, not only with arrays.

`@@get` should be implemented only by “Map like” data structures. Destructuring is usually used to extract deeply nested data from `Object`. I find hard to believe that someone would deliberately use destructuring on `Map` or similar structure to extract methods:

```
// very strange use of destructuring, don’t believe anyone is doing that
const {get, has, set} = myMap // instance of Map()
```

Much more common use case is that you have nested structure of “Map like” structures and want to easily retrieve values.

Btw. this change is backward compatible, because it does not change behavior of existing code. It just gives you ability to provide users with new datastructures.

>
> Also, destructuring patterns are meant to match, and be the logical inverse of, literal syntax. Consequently, from my perspective at least, extensible destructuring would require first introducing extensible literal syntax in a symmetric manner. I think it would be unnecessarily surprising if for random patterns they didn't match up (worse, if you cannot even tell the meaning syntactically, but it depends on whatever object you happen to get).
As I have pointed out, this is not true for iterable destructuring.

```
[a, b, c] = someIterable; // someIterable does not have to be Array
```

This can be similarly surprising:
`someIterable[0] !== a // true`

Thanks,

Samuel
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

smime.p7s (4K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

RE: Extensible destructuring proposal

Domenic Denicola
For maps you can just do

```js
const [[k1, v1], [k2, v2], ...rest] = map.entries();
```

There is no need to add more complexity to object destructuring (which should only be used for objects and their string keys).

-----Original Message-----
From: es-discuss [mailto:[hidden email]] On Behalf Of Samuel Hapák
Sent: Tuesday, July 21, 2015 08:29
To: es-discuss
Subject: Re: Extensible destructuring proposal


> On 21.7.2015, at 9:34, Andreas Rossberg <[hidden email]> wrote:
>
> People reading code will (rightfully) expect destructuring to be syntactic sugar for property access. I don't think it's worth breaking that equivalence. If you want user-defined patterns then they should be syntactically distinct from existing forms.

This is already not true for array destructuring. You can use it with any iterables, not only with arrays.

`@@get` should be implemented only by “Map like” data structures. Destructuring is usually used to extract deeply nested data from `Object`. I find hard to believe that someone would deliberately use destructuring on `Map` or similar structure to extract methods:

```
// very strange use of destructuring, don’t believe anyone is doing that const {get, has, set} = myMap // instance of Map() ```

Much more common use case is that you have nested structure of “Map like” structures and want to easily retrieve values.

Btw. this change is backward compatible, because it does not change behavior of existing code. It just gives you ability to provide users with new datastructures.

>
> Also, destructuring patterns are meant to match, and be the logical inverse of, literal syntax. Consequently, from my perspective at least, extensible destructuring would require first introducing extensible literal syntax in a symmetric manner. I think it would be unnecessarily surprising if for random patterns they didn't match up (worse, if you cannot even tell the meaning syntactically, but it depends on whatever object you happen to get).
As I have pointed out, this is not true for iterable destructuring.

```
[a, b, c] = someIterable; // someIterable does not have to be Array ```

This can be similarly surprising:
`someIterable[0] !== a // true`

Thanks,

Samuel
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Extensible destructuring proposal

Bergi
In reply to this post by Samuel Hapák
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?

  Bergi
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Extensible destructuring proposal

Samuel Hapák
In reply to this post by Claude Pache

> On 21.7.2015, at 12:42, Claude Pache <[hidden email]> wrote:
>
> For example, one can imagine something like:
>
> ```js
>    const {author: {name: {first, last}, birthdate}} = book.toObject()
> ```

There are two issues I see here:
- `book.toObject()` would have to do deep conversion and you may not want it. Let’s say birthdate is immutable map `{day, month, year}`*. This would convert `birthdate` to `Object` even though you didn’t want that.

- this can handle only String keys. My proposal could be extended so this would work:

```js
   const {[someNonStringKey]: value} = someMap;
```
We already have a syntax for that in es6.

PS: * I know we have `Date()` for that purpose. Just for demonstration.

Samuel







_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

smime.p7s (4K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Extensible destructuring proposal

Samuel Hapák
In reply to this post by Domenic Denicola

> On 21.7.2015, at 15:09, Domenic Denicola <[hidden email]> wrote:
>
> For maps you can just do
>
> ```js
> const [[k1, v1], [k2, v2], ...rest] = map.entries();
> ```
>
> There is no need to add more complexity to object destructuring (which should only be used for objects and their string keys).

Could you please explain it on example?

Let’s say I have

```
let book = Map{author: {name: “John”, surname: “Doe”}, birthdate: “10-10-1990”};
```

How would you extract `birthdate`? How would you extract `name`?

Thanks,

Samuel
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

smime.p7s (4K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Extensible destructuring proposal

Samuel Hapák
In reply to this post by Bergi

> On 21.7.2015, at 16:23, Bergi <[hidden email]> wrote:
>
> 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.

Thanks Bergi,

I find your idea really interesting. If get it, benefit of your approach is that user explicitly specifies how to extract data instead of relying on extraction method defined by object being extracted.

This way, you can create multiple competing extractors, so your solution is a lot more flexible than mine. Actually, mine proposal is just special case of yours. I could implement `E[@@extractor]` that just tries to find `__get__` method on object being extracted and uses it.

The only downside I see is the verbosity.

Could you please elaborate more on the use cases for this? I am not used to Scala so my imagination is currently very limited:) I know that I would really really need different destructuring for different object types (otherwise it is insanely verbose to use Immutable Maps), but I can’t think of use case for having multiple different destructurings for single type.

Could you show some examples? Thanks!

Samuel






_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

smime.p7s (4K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

RE: Extensible destructuring proposal

Domenic Denicola
In reply to this post by Samuel Hapák
From: Samuel Hapák [mailto:[hidden email]]

> Could you please explain it on example?
>
> Let’s say I have
>
> ```
> let book = Map{author: {name: “John”, surname: “Doe”}, birthdate: “10-10-1990”};
> ```
>
> How would you extract `birthdate`? How would you extract `name`?

Your syntax here is invalid in at least four different ways. Let's assume you wrote something with valid syntax, like

```js
let book = new Map([["author", { name: "John", surname: "Doe" }], ["birthdate", "10-10-1990"]]);
```

Then:

```js
const [[, { name }], [, birthdate]] = book.entries();
```

If this is still confusing, you may wish to turn to StackOverflow for clarification, instead of es-discuss. You can test such things in Firefox, although you need to use `var` instead of `const` or `let`.
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Extensible destructuring proposal

Bergi
In reply to this post by Domenic Denicola
Domenic Denicola schrieb:
> For maps you can just do
>
> ```js
> const [[k1, v1], [k2, v2], ...rest] = map.entries();
> ```

The problem with this is that you would need to know the order of the
keys in the map. Your code does only extract the "first" and "second"
key-value pairs, allowing us to get the key values of them, but this
syntax does not allow us to extract the value for a given key from
somewhere in the map.
Predictability is all fine, but I still consider maps to be inherently
unordered.

  Bergi
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Extensible destructuring proposal

Domenic Denicola
In reply to this post by Samuel Hapák

Well,  the spec says they are ordered, so I'm not sure where you're getting that from.

 

From: Bergi <[hidden email]>
Sent: Jul 21, 2015 8:53 AM
To: Domenic Denicola; es-discuss
Subject: Re: Extensible destructuring proposal

Domenic Denicola schrieb:
> For maps you can just do
>
> ```js
> const [[k1, v1], [k2, v2], ...rest] = map.entries();
> ```

The problem with this is that you would need to know the order of the
keys in the map. Your code does only extract the "first" and "second"
key-value pairs, allowing us to get the key values of them, but this
syntax does not allow us to extract the value for a given key from
somewhere in the map.
Predictability is all fine, but I still consider maps to be inherently
unordered.

  Bergi


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Extensible destructuring proposal

Ben Newman
In reply to this post by Bergi
I too am fond of Scala's extensible pattern matching. Before I knew about Scala's approach, I thoughtlessly agreed with the conventional wisdom that pattern matching and object-oriented programming are necessarily at odds. Letting objects define their own destructuring semantics shows that wisdom to be mistaken, and your Symbol.extractor method feels like a perfectly ECMAScript-y way to implement it.

That said, virtually every time I've written an unapply or unapplySeq method in Scala, it has been with multi-case pattern matching in mind, and we're only talking about destructuring assignment here, which I suppose is like a single-case pattern match.

If you have time/motivation to put together a proposal for Symbol.extractor, I would very much encourage you to think about the possibility of introducing multi-case pattern matching as well, as I think that would add significant value to the proposal, as well as highlighting some tricky issues.

I'd be happy to review and/or help champion such a proposal, if it works out as nicely as I hope!

Ben

On Tue, Jul 21, 2015 at 10:23 AM Bergi <[hidden email]> 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?

  Bergi
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Extensible destructuring proposal

Bergi
In reply to this post by Samuel Hapák
Samuel Hapák schrieb:

> I find your idea really interesting. If get it, benefit of your approach is that user explicitly specifies how to extract data instead of relying on extraction method defined by object being extracted.
> This way, you can create multiple competing extractors

That wasn't my primary goal (indeed most data structures would have only
a single extractor).
The main benefits I see are:
* explicit is better than implicit
* works anywhere in a destructuring pattern, not only the topmost level
* can be chosen not to be used (e.g. for `let {size} = myMap;`)

> The only downside I see is the verbosity.

That's an advantage imo :-)

> Could you show some examples? Thanks!

I don't think there's much more than the ones I already gave.
Notice that those `NoOptions` and `WithOptions()` was even an example
for multiple extractors to be used for "destructuring" factory functions
(by applying them), though I don't know whether that's the best solution
for this `import` problem.

  Bergi

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Extensible destructuring proposal

Bergi
In reply to this post by Ben Newman
Ben Newman schrieb:

> That said, virtually every time I've written an unapply or unapplySeq
> method in Scala, it has been with multi-case pattern matching in mind, and
> we're only talking about destructuring assignment here, which I suppose is
> like a single-case pattern match.

Right, we don't really have pattern matching in ES yet. I don't want to
introduce that as well, it would be a pretty heavy change imo.

> If you have time/motivation to put together a proposal for
> Symbol.extractor, I would very much encourage you to think about the
> possibility of introducing multi-case pattern matching as well, as I think
> that would add significant value to the proposal, as well as highlighting
> some tricky issues.

I've seen that Scala returns an Option for a pattern. My first thought
was to make @@extractor return an empty iterator, but I'm not sure
whether that's semantically sound.
We then could consider an iterator to be "not matching" if any of the
target elements are left `undefined`, i.e. when the iterator is
exhausted before all elements have gotten a value, similar to default
initialisers are handled today.
Do you think that is viable?

  Bergi
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Extensible destructuring proposal

Bergi
In reply to this post by Domenic Denicola
Domenic Denicola schrieb:
> Well,  the spec says they are ordered, so I'm not sure where you're getting that from.

Yes, the spec defines an order to make iteration predictable and
consistent, but that doesn't mean anyone would use a `Map` for an
ordered structure. I would consider

     new Map(Object.entries({a: 1, b: 2}))

and

     new Map(Object.entries({b: 2, a: 1}))

to be equivalent for all purposes of an algorithm that uses commutative
operators.

  Bergi
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Extensible destructuring proposal

Andreas Rossberg-4
In reply to this post by Domenic Denicola
I think the example actually reveals a deeper issue with the motivation: the desire to destructure maps like here is rooted in a category error. Destructuring is designed to apply to objects from the program domain, while maps are typically meant to encode data from the problem domain.

Or, in other words: destructuring is only useful when you know the keys at programming time (i.e., statically). But if that is the case, there is rarely a good reason to use a map.

/Andreas


On 21 July 2015 at 18:12, Domenic Denicola <[hidden email]> wrote:

Well,  the spec says they are ordered, so I'm not sure where you're getting that from.

 

From: Bergi <[hidden email]>
Sent: Jul 21, 2015 8:53 AM
To: Domenic Denicola; es-discuss
Subject: Re: Extensible destructuring proposal

Domenic Denicola schrieb:
> For maps you can just do
>
> ```js
> const [[k1, v1], [k2, v2], ...rest] = map.entries();
> ```

The problem with this is that you would need to know the order of the
keys in the map. Your code does only extract the "first" and "second"
key-value pairs, allowing us to get the key values of them, but this
syntax does not allow us to extract the value for a given key from
somewhere in the map.
Predictability is all fine, but I still consider maps to be inherently
unordered.

  Bergi


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Extensible destructuring proposal

Samuel Hapák
In reply to this post by Domenic Denicola

> On 21.7.2015, at 17:19, Domenic Denicola <[hidden email]> wrote:
>
> From: Samuel Hapák [mailto:[hidden email]]
>
>> Could you please explain it on example?
>>
>> Let’s say I have
>>
>> ```
>> let book = Map{author: {name: “John”, surname: “Doe”}, birthdate: “10-10-1990”};
>> ```
>>
>> How would you extract `birthdate`? How would you extract `name`?
>
> Your syntax here is invalid in at least four different ways.
> If this is still confusing, you may wish to turn to StackOverflow for clarification, instead of es-discuss.
I apologize for the syntax mistakes I made. I totally understand you receive tons of proposals from people who don’t bother to learn JavaScript. I understand that this pissed you off and I am sorry for that. My bad.

Here is the valid syntax:

```js
let book = new Map([['author', Map([['name', 'John'], ['surname', 'Doe']]), ['birthdate', '10-10-1990']]);
let book2 = new Map([['birthdate', '10-10-1990'], ['author', Map([['name', 'John'], ['surname', 'Doe']])]]);
```

Now, I wish to extract `birthdate` and `name`. I can't rely on the order of elements, because the code should accept any `book` that has same shape. Let's say, ordering of the items in the map is not the part of the contract. So, to clarify this, I want to write function that accepts `book` or `book2` and inside, it extracts `birthdate` and `name`. The code should work with both `book` and `book2`.

I feel, that your solution is unable to achieve this, but I can be mistaken.

Thanks!

Samuel







_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

smime.p7s (4K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Extensible destructuring proposal

Samuel Hapák
In reply to this post by Andreas Rossberg-4

On 21.7.2015, at 20:16, Andreas Rossberg <[hidden email]> wrote:

Or, in other words: destructuring is only useful when you know the keys at programming time (i.e., statically). But if that is the case, there is rarely a good reason to use a map.

Actually, the main motivation is to use Immutable Map (https://facebook.github.io/immutable-js/).

All examples shown here displayed only keys known statically (at programming time). I just mentioned that it could be nice to allow non-string keys and that we could reuse syntax that currently works for "dynamic" keys. But that definitely is not the core of the discussion here.

Samuel







_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

smime.p7s (4K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Extensible destructuring proposal

Matúš Fedák
In reply to this post by Samuel Hapák
I think the example actually reveals a deeper issue with the motivation:
the desire to destructure maps like here is rooted in a category error.
Destructuring is designed to apply to objects from the program domain,
while maps are typically meant to encode data from the problem domain. Or, in other words: destructuring is only useful when you know the keys at
programming time (i.e., statically). But if that is the case, there is
rarely a good reason to use a map. /Andreas


- Most programs acquire, transform, store, search manage, transmit data
- Data is raw, immutable information
- Many langs turn into something much more elaborate - with types, 'methods' etc
esp. OO conflate process constructs and information constructs
Rich Hickey, the author of Clojure programing language

What is the difference between object from domain and data from domain? If I get a json (from some service) and I statically know what keys it has I have an ability to destructure it. But if I convert JSON to an immutable structure (or to a Map) I'm losing this ability somehow. That's strange, since I didn't change abstraction, only actual implementation of the underlying data structure.

```
// this is possible because json return object and array like data structure
const {name, time} = getJsonMap();
// this is not possible because now it will be stored as ImmutableMap
const {name, time} = Immutable.fromJS(getJsonMap());

// but if I would have an array then this is currently possible
const [first, second] = getJsonArray();
// and also this is possible because array destructuring work with iterables and immuatableArray can be iterated 
const [first, second] = Immutable.fromJS(getJsonArray());
```

To sum it up, I would be really happy to see generalization of object destructuring. I don't have a strong opinion about original proposal and Scala-flavoured one. I consider array proposal general enough (since your custom object can support it). Only debatable advantage of Scala-proposal is that you don't lose ability to destructure objects if they define their custom destructuring logic.
```
// Original proposal
let {a, b} = new Map([["a", 2], ["b": 3]]); // this will be completely ok
let {size} = new Map([["a", 2], ["b": 3]]); // this will not be possible
// Scala proposal
let Map{a, b} = new Map([["a", 2], ["b": 3]]); // this will be completely ok
let {size} = new Map([["a", 2], ["b": 3]]); // this will be also doable
```
However, I don't see a point in having possibility to destructure functions from Map or ImmutableMap or other primitives that decide to implement custom object-destructuring logic.

Maty

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
12