

Immutable JavaScript data structures, backwards-compatible with arrays, objects - rtfeldman
https://github.com/rtfeldman/seamless-immutable

======
arasmussen

      var array = Immutable(["totally", "immutable", {hammer: "Can’t Touch This"}]);
    
      array[1] = "I'm going to mutate you!"
      array[1] // "immutable"
    

I find it a little weird that the result of trying to mutate an immutable
object is to silently fail the mutation. Couldn't this hide errors where the
developer expects something to mutate because they didn't realize it was
immutable? Shouldn't it throw instead?

Edit: After reading the documentation more thoroughly, I saw "All the methods
that would normally mutate the data structures instead throw ImmutableError."
Looks like the first section isn't actually accurate then?

~~~
rtfeldman
(Library author here.) Unfortunately, in JavaScript it's not possible to
override array element reassignment behavior. You can call Object.freeze on
the array, which makes reassignment silently do nothing, but you cannot
override it to throw an exception.

The reason the docs say "the methods that would normally mutate..." is that in
the specific case of _methods_ (e.g. array.push()), the library can and does
override them to throw exceptions.

I would certainly prefer to make that example throw an exception, but it's
simply not possible in JS. :)

~~~
underwater
Object.freeze will throw if you `'use strict';`.

~~~
rtfeldman
Very true...I should note that in the documentation. Thanks!

------
hesselink
I wonder what the performance of this is. While functional languages like
Haskell are optimized for these kinds of data structures, I doubt Javascript
runtimes currently are. We've been bitten before by writing code in too much
of a functional style and getting terrible performance, so benchmarks would be
really useful before we'd start to use this.

~~~
Sonata
Haskell and Clojure both use structure-sharing data structures, which allow
immutability without the cost of copying the entire structure whenever you
want to make an update. They also use laziness to improve the performance of
their data structures.

If you want an implementation of these ideas in JS, Immutable.js [0] or Mori
[1] are the leading libraries. seamless-immutable doesn't use these
techniques, so it probably wouldn't perform well on large data sets. The
benefit of it is that the immutable objects can be used as drop-in
replacements for their native JS equivalents in some situations.

Full disclosure: I've contributed to Immutable.js

[0] [https://github.com/facebook/immutable-
js](https://github.com/facebook/immutable-js)

[1] [https://github.com/swannodette/mori](https://github.com/swannodette/mori)

------
shangxiao
Good timing. I was thinking about taking a look at immutable.js after the HN
post a couple of days ago [1] and now I have an alternative to compare it
with.

[1]
[https://news.ycombinator.com/item?id=8541496](https://news.ycombinator.com/item?id=8541496)

------
evv
How does this compare to [https://github.com/facebook/immutable-
js](https://github.com/facebook/immutable-js) ? Has anybody used both?

~~~
Sonata
From what I can see, seamless-immutable basically just enforces immutability
on native JavaScript data structures. Immutable.js on the other hand,
implements full persistent data structures, which give much better time
complexity guarantees about important operations. Immutable.js also has a rich
API designed for manipulating immutable data structures and uses lazy
evaluation for methods like map, filter and concat, which really improves
performance when chaining chose operations.

