Re:Immutable JavaScript data structures, backwards-compatibl...
by arasmussen on Monday November 03, 2014 @02:09PM
(#8552751)
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?
Re:Immutable JavaScript data structures, backwards-compatibl...
by rtfeldman on Monday November 03, 2014 @02:26PM
(#8552862)
(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. :)
__DEV__ = true;
var array = ['a', 'b', 'c']
deepFreezeAndThrowOnMutationInDev(array)
array[0] = 10;
Error: You attempted to set the key `0` with the value `10` on an object that is meant to be immutable and has been frozen.
Re:Immutable JavaScript data structures, backwards-compatibl...
by arasmussen on Monday November 03, 2014 @04:46PM
(#8553732)
Thanks for sharing that tidbit of information. I did not know that and now I do, I appreciate it!
I wonder what the reason behind that is, if you're feeling extra motivated you could even look into having a conversation with the folks who decide what future versions of JS look like to add something like it. I am a huge proponent of immutability and can see how being able to override array element assignment behaviors would improve your library.
Re:Immutable JavaScript data structures, backwards-compatibl...
by virmundi on Monday November 03, 2014 @05:20PM
(#8553933)
I spent the better part of an hour cursing about this. Chrome returns frozen objects from Web SQL. Now I didn't know that a poor language like Javascript had a Frozen! No errors! Finally found it when I queried for Angular failing to update objects because the looked immutable.
Re:Immutable JavaScript data structures, backwards-compatibl...
by hesselink on Monday November 03, 2014 @05:06PM
(#8553871)
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.
Re:Immutable JavaScript data structures, backwards-compatibl...
by Sonata on Monday November 03, 2014 @07:41PM
(#8554543)
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.
Re:Immutable JavaScript data structures, backwards-compatibl...
by shanemhansen on Monday November 03, 2014 @07:01PM
(#8554392)
I agree that benchmarks are the final arbiter, but javascript engines are pretty well optimized for handling garbage. So if you're going to be making garbage, javascript isn't a bad language to do it in, and immutable data structure algorithmic performance isn't going to change in js.
Re:Immutable JavaScript data structures, backwards-compatibl...
by shangxiao on Monday November 03, 2014 @03:22PM
(#8553231)
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.
Re:Immutable JavaScript data structures, backwards-compatibl...
by Sonata on Monday November 03, 2014 @07:28PM
(#8554498)
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.
Re:Immutable JavaScript data structures, backwards-compatibl...
by pimlottc on Tuesday November 04, 2014 @01:54AM
(#8555408)
They both mimic the standard Array/Map/Set methods but differ in how they handle mutating methods like push and set. In Facebook's version, these functions return a new immutable instance with the values changed appropriately, while this one throws an error. It also provides a few new methods to combine/transform existing immutables.
I like the look of this one better. IMHO Facebook's approach will lead to confusion and subtle errors when their immutables are mixed up with normal objects and arrays.
Personally I think this is think that's an unwise decision that will lead to confusion and subtle errors.
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?
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. :)
https://gist.github.com/vjeux/6b390e6a6bb51e24b646
I wonder what the reason behind that is, if you're feeling extra motivated you could even look into having a conversation with the folks who decide what future versions of JS look like to add something like it. I am a huge proponent of immutability and can see how being able to override array element assignment behaviors would improve your library.
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
[1] https://github.com/swannodette/mori
[1] https://news.ycombinator.com/item?id=8541496
I like the look of this one better. IMHO Facebook's approach will lead to confusion and subtle errors when their immutables are mixed up with normal objects and arrays. Personally I think this is think that's an unwise decision that will lead to confusion and subtle errors.
This one is directly on js objects (seamless-immutable).