The problem is that what you propose is a leaky abstraction, because pattern matching works on classes and not on types, so it's not a reverse link.

("Leaky abstraction" is sort of an inflammatory term.)

What I think you're getting at is that some objects will have state that you can "put in", but can't "take out".  The mathematical relationship here is "embedding projection pair" (this is similar to an adjoint functor pair in some ways.)

A good example of this relationship is int and Integer.  Every int corresponds to an Integer, and *almost* every Integer (except null) corresponds to an int.  Imagine there are two functions e : int -> Integer and p : Integer -> int, where p(null) = bottom. Composing e-then-p is an identity; composing p-then-e can lose some information, but we can characterize the information loss.  Records form this same relationship with their cartesian product space (assuming you follow the refined contract outlined in Record::equals).  When you have this relationship, you get some very nice properties, such as "withers" and serialization basically for free.  The relationship between a ctor and the corresponding dtor also has this structure.  So yes, going backwards is "lossy", but in a controlled way.  This turns out to be good enough for a lot of things.

Let say we have a class with two shapes/deconstruction

class A {
  deconstructor (B) { ... }
  deconstructor (C) { ... }
}

With the pattern A(D d), D is a runtime class not a type, you have no idea if it means
  instanceof A a && B b = a.deconstructor() && b instanceof D
or
  instanceof A a && C c = a.deconstructor() && c instanceof D

You can have types in the dtor bindings, just as you can have types in the constructor arguments.  Both may use the class type variables, as they are instance "members".

Unlike with a method call (constructor call) where the type of the arguments are available, with the pattern matching, you do not have the types of the arguments, only runtime classes to match.

This is where the rule of "downcast compatible" comes in.  We see this show up in GADT-like examples (the rules of which are next on our parade.)  For example, if we have:

    sealed class Node<T> { }
    record IntNode(int x) implements Node<int> { }

then when we switch on a Node<T>:

    switch (aNode) {
        case IntNode n: ...
    }

we may conclude, in the consequent of the appropriate case, that T=int.  (Read the Kennedy and Russo paper for details.)

Similarly, if we have:

    List<String> list = ...

then when matching, we may conclude that if its an ArrayList, its an ArrayLIst<String>:

    switch (list) {
        case ArrayList<String> a: ...
    }

but could not say `case ArrayList<Integer>`, because that is inconsistent with the target type.

So, while we can't necessarily distinguish between Foo<String> and Foo<Integer> because of erasure, that doesn't mean we can't use types; its just that we can't conclude things that the generic type system won't let us.

As i said, it's a question where OOP and DOD (data oriented design ?) disagree one with the other.

I don't think they disagree at all.  They are both useful tools for modeling things; one is good for modeling entities and processes, the other for modeling data, using a common vocabulary.  Our systems may have both!

And this is a problem specific to the deconstructor, for named pattern method, there is no such problem, obviously a user can add as many pattern methods he/she want.

Because there's no name, we are limited to overloads that are distinct up to erasure; constructors have the same restriction.

    But for each way of putting together the data, there should be a
corresponding way to take it apart.

if the pattern matching was a real inverse link, yes, maybe.

I think the word "real" is doing too much lifting in that sentence.

The problem is that varargs pattern can also recognizes a record with no record or class with a deconstructor with no varargs.

As can a constructor.


You think term of inverse function, we have varargs constructors so we should have varargs pattern, but a pattern is not an inverse function.

You are interpreting "inverse" too strictly -- and then attempting to use that to prematurely bury the concept.

We have the freedom to provide a simpler model.

I think the reality is that you want this to be a smaller, less ambitious feature than is being planned here.  That's a totally valid opinion!  But I think its just a difference of opinion on how much to invest vs how much we get out.

But by all means, try to outline (in a single mail, please) your vision for a simpler model.

Reply via email to