Code Monkey home page Code Monkey logo

Comments (11)

aearly avatar aearly commented on August 19, 2024

You are correct that icepick is in the first camp. One thing to note, though, is that there are no "instances" -- icepick only returns plain (but frozen) objects that can be used with anything that doesn't try to modify them (direct property access, arr.map(), etc..). seamless-immutable is not quite in the second camp -- it still returns plain objects, but adds a few more methods to them for convenience.

If you want mutable data back out, they way to get it is to deeply clone the object. You can use something like Lodash _.cloneDeep or even JSON.parse(JSON.stringify(obj)).

Would a i.thaw() function that does this be helpful?

from icepick.

bitinn avatar bitinn commented on August 19, 2024

Having an api would help, thaw sounds like a good name.

I just realize once we freeze an object there is no unfreeze, we can only clone it to a new one. It would seem that thaw then mutate then freeze again will have roughly the same performance as diffing (eg. assoc etc.) the immutable itself (which does the same thing)?

If so, perhaps we should just diff the immutable itself, and avoid thaw most of the time.

from icepick.

aearly avatar aearly commented on August 19, 2024

What do you mean by "diff the immutable"? The proper way to see if things have changed would be to see if objects are still reference-equal to their previous values.

from icepick.

bitinn avatar bitinn commented on August 19, 2024

My wording was probably wrong, sorry about that. I simply meant something like newColl = i.assoc(coll, "b", 3). And I was talking about how icepick would be updating b in this case.

If I understand correctly:

  • Say coll is frozen already, when you are creating the newColl, you have to copy coll's value into a mutable object again, and then change b, and then freeze it again.
  • But unlike the initial i.freeze(coll), we don't have to freeze any data recursively, only the object that has changed, ie. the object containing b.
  • So this is faster than i.thaw(coll); coll.b = 3; i.freeze(coll); particularly for larger coll, because we don't need to freeze other part of it.

True?

If so then we shouldn't use thaw/freeze for mutation, we should try to change coll into a newColl with assoc, which makes thaw less desirable.

TL;DR: i.thaw is nice to have as a helper function, but probably shouldn't be used for mutation.

from icepick.

aearly avatar aearly commented on August 19, 2024

Yep, I think you understand. If you look at the implementation of i.assoc that's essentially what it does -- (shallow)copy, modify, freeze.

from icepick.

bitinn avatar bitinn commented on August 19, 2024

I have been using icepick in production for a month now and things are working great, though I did find i.thaw to be a useful addition, imagine this scenario:

Let say we are using a virtual-dom rendering system that allow template to be rendered both server-side and client-side. Now imagine we are to render a list of tweets.

Because data from backend are just normal object, we are doing something like this:

    var tweets = tweets.map(function(tweet, i) {
        return tweetView(tweet);
    });

Say we have a variable that's global, but is needed when rendering tweetView:

    var domain = 'twitter.com';
    var tweets = tweets.map(function(tweet, i) {
        tweet.domain = domain;
        return tweetView(tweet);
    });

On server-side this is fine, but on client-side our model is an icepick-powered store, which means tweet.domain = domain; will fail.

At this point we have a few options:

  1. Make server use icepick as well, which doesn't make much sense as data is used only once.
  2. Do an Object.isForzen check, and set data differently. This works but expose icepick api to virtual-dom template, which feel kinda weird.
  3. i.thaw, modify and pass the data as normal object. Unfortunately we will take a performance penalty here from clone.

Do you see any better approach?

from icepick.

aearly avatar aearly commented on August 19, 2024

Could you do something like:

    var domain = 'twitter.com';
    var tweetViews = tweets.map(function(tweet, i) {
        return tweetView(i.assoc(tweet, "domain", domain));
    });

The update to the tweet would be discarded, but it would work. The other option would be to update all your tweets with it:

var tweets = i.map(tweets, function (tweet) {
  return i.assoc(tweet, "domain", domain);
});

// and then

var tweetViews = tweets.map(function(tweet, i) {
    return tweetView(tweet);
});

from icepick.

bitinn avatar bitinn commented on August 19, 2024

One thing I am not sure about: on server-side my tweets is a plain array that's not frozen, does i.map and i.assoc still work?

from icepick.

aearly avatar aearly commented on August 19, 2024

Yes. It'll work with any plain JS Array or Object, and they don't have to be frozen.

from icepick.

bitinn avatar bitinn commented on August 19, 2024

Wow cheers, would i.assoc actually be faster than i.thaw in my use case though? Both of them do clone but i.thaw will have to do it recursively.

from icepick.

aearly avatar aearly commented on August 19, 2024

Yes, assoc would be faster since it's a shallow clone.

from icepick.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.