4 ms·
Not all paradigms are equally useful. Mutable state pretends that change happens instantaneously, which isn't how the real world works. Let's say you observe t
by weavejester 13y ago
Not all paradigms are equally useful. Mutable state pretends that change happens instantaneously, which isn't how the real world works.
Let's say you observe the state of a lightbulb. You might say "The lightbulb is on," but the lightbulb could be turned off, rendering your statement technically invalid. So instead you might say, "The lightbulb is on, now", but even that's not necessarily true, as in the time it took the light to reach your eyes, the lightbulb could have been turned off. So the most accurate description you could give would be "The lightbulb was on, 10 nanoseconds ago."
Systems with mutable state have no explicit time element. So "x = 1" is analogous to saying "The lightbulb is on." Systems with immutable state have to be more specific about time, so they might say "x[when t=0] = 1". Can you see how this is a more accurate representation?
Mutability is really only useful under the following circumstances:
1. You need performance.
2. You have only one thread.
3. You are performing no I/O.
- RivieraKid 13y agoI'm not really sure how the lightbulb metphor translates into real world code, what kind of situation does it describe? In Java, I can very easily choose between mutability and immutability. If I put "final" in the variable declaration, the variable is immutable. So what I usually do is default to immutability but opt out if needed. Which is very often, usually because 1) it would make the code more elegant and easier to understand 2) for performance reasons. You are performing no I/O. Why does I/O make mutability useless?
- weavejester 13y agoIt describes a situation where read latency is a factor, which is any situation where you cannot guarantee a single observer. This is true if you have multiple threads, but also true if you're accessing a shared I/O resource, such as a filesystem. Mutable OOP presents the fiction that you can retrieve the current value of a property or object, but we know this isn't true. In reality, all we can do is to find a past value of a property, because there's always some latency involved in reading. If it's a single value, maybe the latency is only a few nanoseconds. If it's a lookup against a hashtable, perhaps we're talking microseconds. If we need to access I/O, our latency increases to milliseconds or higher. The more concurrency and latency in a system, the harder it is to maintain the fiction that latency does not exist. It's worth asking whether a model that falls apart so quickly (which it does whenever you need a synchronized method or data structure) is actually useful to have in the first place. Java does allow variables to be marked as being immutable using the final keyword, but it doesn't have very good tools for dealing with immutable data. It doesn't have efficient immutable data structures in its core language and it has no tail call optimisation, or even a pseudo-TCO structure like Clojure's loop/recur. In short, it's much more difficult to use immutable data in Java than it is in a functional language like Clojure.
- RivieraKid 13y agoOh, I understand now, you were talking about shared mutable state. I think that Java has a solid support for parallelism and there's more in libraries (e.g. implementations of the actor model). When I share data between threads, I almost always use immutable objects (one can even mark immutable classes with an annotation to make it explicit). Clojure's software transactional memory is a very interesting feature but I haven't really played with it. Java does allow variables to be marked as being immutable using the final keyword, but it doesn't have very good tools for dealing with immutable data. It doesn't have efficient immutable data structures in its core language and it has no tail call optimisation, or even a pseudo-TCO structure like Clojure's loop/recur. In short, it's much more difficult to use immutable data in Java than it is in a functional language like Clojure. Mostly agree, functional languages like Clojure are definitely more immutable-friendly.
- weavejester 13y agoWell, sure, but why would you want local mutable state? In some cases it's more efficient to alter transient data in place, but mutability makes it much harder (and usually less efficient) to effectively compose functionality. I guess Java does make it seem like the opposite is the case; that it's easier to work with mutable data, and that immutability is just a needless restriction. However, in languages with lambdas and higher-level functions, local mutability is rarely required, and becomes a hindrance rather than a help. Just look at how many times "options.dup" turns up in Ruby code: https://github.com/search?q=options.dup&ref=cmdform&type=Code https://github.com/search?q=options.dup&ref=cmdform&type=Cod... . It's an annoying pattern in Ruby to work around the lack of immutable maps in the core language.