Extensible destructuring proposal

Samuel Hapák samuel.hapak at vacuumapps.com
Wed Aug 5 19:26:40 UTC 2015

Thank you for your reply Andreas!

So, let's split this discussion into two parts:

i) Whether there is a good use case for non-standard data structures like Immutable.js in place of standard Objects.

ii) If so, how to proceed with simplifying destructuring for these data structures.

Let's discuss the i) first.

> On 4.8.2015, at 14:26, Andreas Rossberg <rossberg at google.com> wrote:
> As for a more Scala-like variant with distinguished syntax, I'm fine with that semantically. But I still don't buy the specific motivation with maps. Can you give a practical example where you'd want to create a map (immutable or not) for something that is just a record of statically known shape? And explain _why_ you need to do that? Surely it can't be immutability, since objects can be frozen, too.

Some people from FRP community believe that using non-mutable values is superior over using mutating values. There are lot of resources online why functional people prefer non-mutable values, one of them is famous Rich Hickeys' talk: http://www.infoq.com/presentations/Value-Values <http://www.infoq.com/presentations/Value-Values>

But we've got `Object.freeze()`, right? It should be remedy to all our problems, right? Well, nope.

The reason, why people use libraries like:
https://github.com/facebook/immutable-js/ <https://github.com/facebook/immutable-js/> (7760 stars)
https://github.com/swannodette/mori <https://github.com/swannodette/mori> (1692 stars)

is not object freezing. Actually, they don't freeze objects at all! They are about how to manipulate immutable data easily and **efficiently**.

Following code in traditional mutable programs:


let book = {title: "Harry Potter", author: {name: {first: "Joanne", last: "Rowling"}, age: 49}}

// It was J. K. Rowling's birthday at July 31st, let's increase the age


Is hard to do when you deeply freeze the structure. But you can introduce some helpers for the task:

let book = deeplyFreeze({title: "Harry Potter", author: {name: {first: "Joanne", last: "Rowling"}, age: 49}})

// We use some convenience updateIn helper that clones the frozen structure and creates new updated:
book = updateIn(book, ['author', 'age'], (age) => age + 1)

// results in
// deeplyFreeze({title: "Harry Potter", author: {name: {first: "Joanne", last: "Rowling"}, age: 50}})


That was nice, but slooooooow:( Cloning objects on each tiny change. That's hardly efficient.

Fortunatelly, Phil Bagwell and Rich Hickey came up with cool concept of structural sharing that can make immutable (also known as persistent) data structures very efficient. It gives practically O(1) for both updates and lookups. This is nice introductory post:
http://hypirion.com/musings/understanding-persistent-vector-pt-1 <http://hypirion.com/musings/understanding-persistent-vector-pt-1>

The reason why people use immutable.js and mori in JavaScript and why all default data structures in Clojure are based on Bagwell/Hickey algorithms, is that these libraries provide **efficient** way to manipulate immutable datastructures in a **convenient** way.

And there is growin React community that would like to use immutable.js as primary data structures in their programs.

https://facebook.github.io/react/docs/advanced-performance.html#immutable-js-to-the-rescue <https://facebook.github.io/react/docs/advanced-performance.html#immutable-js-to-the-rescue>

So, let me sum up:

There is a growing functional/reactive community amongst JavaScript programmers. Ones of key building blocks of functional programming are **efficient** immutable datastructures. These are not native in JavaScript.

Currently the only drawback of using immutable datastructures in javascript is how cumbersome it is to use them. And part of the reason is that destructuring does not work and we have to write:

const first = book.getIn(['author', 'name', 'first'])
const last = book.getIn(['author', 'name', 'last'])
const age = book.getIn(['author', 'age'])

> In particular, it is no longer to write
>   let {a: x, b: y} = unMap(map)
> as you can today, then it would be to move the transformation to the pattern:
>   let Map({a: x, b: y}) = map

But this does not work for nested structures. Like on the example above.

Have I made my motivations more clear now?

Thanks for reading this horribly long email:)


@samuha <https://twitter.com/samuha> (+421 949 410 148)
skype: samuelhapak

Check my availability at https://freebusy.io/samuel.hapak@vacuumapps.com

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150805/eb3c6392/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 3589 bytes
Desc: not available
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20150805/eb3c6392/attachment.p7s>

More information about the es-discuss mailing list