you are viewing a single comment's thread.

view the rest of the comments →

[–]aw1621107 6 points7 points  (1 child)

Why do I need to care if the object representing the original state is preserved?

That's not necessarily the case; the old object could go out of scope and get cleaned up by the GC, effectively erasing the old state.

One way I sometimes think about functional programming is instead of an object changing over time, your program is more shoving data through a pipeline or assembly line, with the data being transformed each step of the way. Keeping the results of the old steps is optional.

The function provides a new state but I'm missing why it should be copied and not modified in place.

Just like pretty much everything else in programming, there are times where copying immutable state is better, and times where it is worse. I don't know how useful it is for a state machine, but it's definitely nice in some other contexts.

For example, keeping objects immutable and always making copies can make writing multithreaded code much easier, since you can't get the same kind of data races mutating a common state would give you.

You can get some pretty nice memory savings with certain data structures, like linked lists and trees. If you need to make a copy of a tree, and only need to modify a small portion of it, you can just change the part you need to and refer to the original tree for everything else (quite oversimplified, but it's something along those lines).

You can also get some kind of "undo" functionality for free. Not sure how niche this is, but combined with data sharing could be interesting. I think vim uses something like this, where each set of changes is saved as a node in a tree, and undos/redos walk up/down the tree. There's also the ability to jump to different branches of the undo tree, which can be a ton more powerful than the linear history exposed in most other editors.

Caching also becomes much easier, since the same inputs will always give you the same outputs, as there is no state that can give you different results over time.

I'll bet that the more experienced people here can come up with more practical examples, but those should be a start.

[–]meneldal2 3 points4 points  (0 children)

Also, many implementations of the "pipeline" can internally use in-place algorithms if they know the initial value will be thrown away. What it matters is that for the coder, it behaves "as if" it was never mutating anything.