4 ms·
Explain why mutation doesn't play well with pattern matching.
by mahkoh 7y ago
Explain why mutation doesn't play well with pattern matching.
- pron 7y agoA pattern requires matching against a piece of data possibly composed of several related components that are assumed to be coherent with one another, not some mutable object. How would you match Point(3, y) against a mutable object, if by the time you grab the y, the x component may no longer be 3 (recall that Java is a multithreaded language, and x could be volatile)? By analogy, think of how matching a regex pattern would work against a mutable array of characters as opposed to an immutable string.
- mahkoh 7y agoDifferent components being in sync is a property of objects in general. E.g. Java's ConcurrentHashMap is mutable but its fields are in sync. For pattern matching to see an in-sync view of the object, the object must provide such a view. If the object allows concurrent modification (most don't) then it must provide a custom view. Otherwise a generated default view should be sufficient. If you look at [1] you can see that Goetz does propose a function that provides such a view for classes and not just records (c-f extractor.) [1] https://cr.openjdk.java.net/~briangoetz/amber/pattern-semantics.html https://cr.openjdk.java.net/~briangoetz/amber/pattern-semant...
- pron 7y agoBut that's exactly what I meant by mutation does not play well with pattern matching: you need to work, sometimes work hard (in fact you need to somehow hide the mutability) to make it work. I'm not sure what you meant exactly by the fields of ConcurrentHashMap being "in sync" (the contents of the hash map certainly aren't and it does not provide a snapshot view), but their coherence requires hard work. Unless you don't know how the particular synchronization mechanism, if any, works, you cannot provide a view suitable for pattern matching, so it cannot, in general, be automatically generated for mutable objects, at least not in a way that works as well as you'd want it to. For example, a naive extractor to a Pair class with two volatile field could return two values that have never been the values of object's fields at any point in time (i.e. you'd pattern-match `case Pair(x, y)` and get, say, x=2 and y=3 despite the pair never having been (2,3)). That "works" in the sense that you have some result, but it's probably not what you want.
- mahkoh 7y agoConcurrentHashMap contains multiple volatile fields. These are kept in sync (i.e. their invariants are preserved) by the ConcurrentHashMap implementation. Concurrent programming being hard is a property of concurrent programming. It being hard does not require pattern matching. Most mutable objects are easy because they don't support concurrent modifications. Therefore pattern matching would not make them harder to implement. Pattern matching such an object while it is being concurrently modified is simply a programmer error just like any other use of the object. Not allowing pattern matching of mutable objects would be similar to not allowing equals and hashCode methods on such objects and for similar reasons.
- pron 7y agoI'm not talking about not allowing. I merely explained, because you asked, why pattern matching does not play well with mutation, and it doesn't. equals and hashCode also don't play well with mutation, and indeed they are not automatically generated for mutable objects, but they are for records. As the author of a class you can provide a reasonable implementation of them, as well as of a deconstructor for pattern-matching, but that requires knowing more about the particulars of the class. There are other reasons for not allowing mutable records, but most -- including pattern matching -- can be summarized as "that's not what records are about, which is being 'dumb' data aggregates". You can read a more detailed discussion of the subject here: https://cr.openjdk.java.net/~briangoetz/amber/datum.html https://cr.openjdk.java.net/~briangoetz/amber/datum.html
- mahkoh 7y ago>I merely explained, because you asked, why pattern matching does not play well with mutation, and it doesn't. What you explained so far is that it doesn't play well with concurrent modification. And then I said that the "not playing well" comes from the concurrent part, not from the modification part. I'm less interested in the philosophy of records and more in the use cases they support.
- 7y ago