Hacker News new | past | comments | ask | show | jobs | submit login

I've build a library Transmutable which falls into the third category :)

it allows to use immutable data structures in mutable-like way, using plain assignments: https://www.npmjs.com/package/transmutable (mutations are not performed but they are just recorded in ES6 Proxy, and object is cloned on commit (sort of copy-on-write), and mutations are then applied).

So it basically enables for writing such things:

    const copy = transform(original, stage => {
        stage.x = 10;
        stage.y = 20;
        stage.foo.bar = 123;
    })
instead of Object.assign / ... mess.



This is a neat idea, hadn't thought of this but it could definitely help me bring new developers into the immutable style more easily.

The only issue with it is, of course, the fact that Proxies are ES6 and everyone still has to deal with old browsers.

I know MobX does similar object observation, and they support IE, but I've never had the time to go into their codebase. Do you know if something like this could be written in a way that allows IE10/11 to support it?

Also, could you elaborate on why it's necessary to use a proxy at all, when in reality you could just do a copy of the object from the very beginning and allow them to do mutations on that?


As far as I know, proxies simply will not work in environments that do not support ES6, because they require purpose-built JS engine support (see some comments at [0] as examples).

MobX works by wrapping plain objects and arrays with its "observable" equivalents. Per [1] , its object support requires fields to already exist, so it knows how to generate wrapper fields accordingly.

As for copying: as I talked about in the "Immutable Update Patterns" section of the Redux docs [2], proper immutable updates require copies of _every_ level of nesting that is being modified. If you want to make an update to `state.a.b.c.d`, you need to make copies of c, b, a, and state. That's doable, but takes work, and can get ugly if you're dealing with nesting by hand. This does lead to frequent mistakes, like assuming that `let newObj = oldObj` makes a copy (it just adds another reference to the same object), or that `Object.assign()` does deep copies (it's only shallow, ie, the first level). It's one of the most common pain points I see for people learning immutability and/or using Redux.

What something like the `transmutable` lib appears to give you is the ability to write perfectly standard imperative mutation code with no extra fluff necessary, even for nested data, and still get proper immutable updates. I'm definitely going to have to play around with it.

[0] https://stackoverflow.com/questions/35025204/javascript-prox...

[1] https://mobx.js.org/refguide/object.html

[2] http://redux.js.org/docs/recipes/reducers/ImmutableUpdatePat...


on the beginning I used getters/setters but I switched to Proxy because it allowed for simpler implementation and more flexibility.

I may consider to switch back into getters/setters, if support of Proxy is really a problem (although getters/setters have its limitations).

There is also Proxy polyfill, although it has the same limitations getters/setters have ("properties you want to proxy must be known at creation time"): https://github.com/GoogleChrome/proxy-polyfill


Nice, I hadn't seen that yet. I'll have to take a look at it later.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: