These are chat archives for mithriljs/mithril.js

Jan 2018
James Forbes
Jan 21 2018 00:04


I distinctly remember you talking about your vdom queries with the proviso that immutability was too expensive to be worth it

That's because I did :D

My weird interpretation for vdom trees uses mutable lenses because there's no point paying the perf cost at that point in the app lifecycle. It's totally fine to mutate the vdom itself because its created from scratch everytime.

But not because it's too expensive to be worth it, it'd probably be fine if it were immutable. But because there's no benefit to immutability there.

Immutability is only useful if we are sharing state. If there's no sharing, then mutable state is in effect immutable from an application perspective. Because if state changes in an application and no-one's around to see it, did it actually change?

The key reason immutability is so useful (beyond all the other subtle things you get), is code in completely disparate parts of an application can reliably share state without any detriment to maintenance or stability. If on the other hand, anyone can mutate the state tree at anytime you need to be judicious with how things are updated and when and who by. That leads you to proxies, and getter/setters and a lot of manual null/type checks because of mistrust of the state tree and other areas of the codebase.

James Forbes
Jan 21 2018 00:12

Part of the value in something like typescript is, you can say, this tree has this shape, and if you want to modify it you have to adhere to the types of properties and structures on that tree. So that saves you from 1/2 the problem. It'll warn you if a value is null, it'll warn you if the type your module expects a value to be isn't what other modules expect it to be.

But... that doesn't help with value changes. So if we have one module that pushes into a list, it might assume the list is non empty from then on. Some time later it may grab the first item. But some other component somewhere else may have reset that list to be empty and now we've got undefined is not a function. Who changed the array? Hard to say. When did it change? No idea.

In most cases the component will just have a conditional to check it's not empty. Multiply that out to most interactions in a system with shared mutable state and you find yourself with a lot more conditionals, and quite often not enough to cover all the permutations of possible failures.

If the tree is immutable, the only way we can propagate changes is to create a new change and send it to the top of our application and have it flow down again. Now we know who changed a value, why, when, how etc. We also can retain our version of the state if we want quite trivially without having to clone anything. We can make a lot more assumptions about our state which saves us writing pointless checks everywhere.

So with all that said you can probably imagine scenarios where immutability is more suitable. And some situations where mutability is fine.

Like for extremely short lived, non shared state, mutation is fine. E.g. If state only moves in one direction and performs one task, mutation is fine, e.g. a command line application, or even some HTTP requests.

But in user interfaces where we have long lived shared state, immutability is incredible.

Isiah Meadows
Jan 21 2018 00:30
@JAForbes Also, mutable state actually makes sense in other cases. But you could represent it with a partial state tree, rather than a full one. With databases in particular, this comes to mind. (It scales well, and you don't actually have to put as much work into making it fast.) There's also GraphQL, which does this to some extent as well.
Barney Carroll
Jan 21 2018 01:34
@JAForbes thanks, this is brilliant
James Forbes
Jan 21 2018 02:16
👍 I think it's a great question to pose, because so many people state immutability is always better and without explanation. But to discuss other things further down the fp line, immutability has to be an assumption, so that may be why.
@isiahmeadows true
Jan 21 2018 23:56
Heh, Typescript gets conditional types, subtraction/filtered types: Microsoft/TypeScript#21316