clojurevalue-typereference-type

In Clojure, is there a meaningful difference between value types and reference types?


I'm starting to realise that there is little distinction between value types and reference types if both are immutable. To test this, I wanted to see how a true lover of immutability like Clojure handles it. Unfortunately, I'm an ignorant C# programmer who speaks neither Java nor Clojure so my Googles have been unhelpful.

In C#, we have a distinction between value types and reference types. This is just the classic "pass-by-value" and "pass-by-reference" distinction. Does any analogous distinction exist in Clojure? I'm certain that it does in Java, although the terminology might not be the same. If it does exist in Clojure, does it only exist because of what it directly inherits from Java (e.g. by importing Java libraries?)?


Solution

  • Even in Java, the distinction doesn't really exist. Sometimes it is convenient to think of objects being passed by reference, in that I can pass an object to a method, the method can mutate the object, and I can see that mutation in the parent method. But really we've just passed the method a pointer to our object, by value, and it dereferences that pointer to modify it.

    This may seem like splitting hairs: isn't an implicit pointer the same as a reference? No, because the method we call can't reassign the pointer for us, the same way that C# could with a ref parameter. For example, if I have an immutable type:

    final class IntPair {
      final int x;
      final int y;
      IntPair(int x, int y) { this.x = x; this.y = y; }
    }
    

    and I pass such an IntPair to a method, I know its x and y fields will be unchanged. The type provides no way to mutate itself, and the language provides no way to replace the object with another.

    Clojure inherits all of these semantics.