This is a static method that "matches" present optionals, and
    returns their contents if present, or a sentinel if not.  The
static pattern Optional::of does the same, just not as a method.

It can not, for several reasons, first you should be able to declare a "virtual" pattern method on an interface and a class that implements that interface should provide a specific implementation of that pattern.

You can, as the document says.  That's an instance pattern (abstract or not).  But that doesn't mean that static patterns don't also make sense.  There's a reason we have static methods, and all the same reasons apply to static patterns.





    This maps to instance/static in a straightforward way: for
    instance patterns, the target is the receiver, for static
    patterns, it is passed as the first input argument.


And here we disagree because you are mixing how the pattern is used inside the switch with how it is declared inside the class. When you use a pattern inside a switch, you have to specify the type because you may first have to do an instanceof, but it doesn't mean that the method that declare the pattern has to be static.

I think you are confused about how this works.  Consider this class (deliberately terrible syntax):

   class FriendOfOptional {
       static<T> Optional<T> makeOptional(T t) { return Optional.of(t); }

       static<T> __partial
                        __pattern
                        __ name = "presentOptional"
                        __target(Optional<T> opt)
                        __bindings(T t)
                        __body {
                                 if (opt.isPresent()) __MATCH_SUCCEED(opt.get());
                                 else __MATCH_FAIL;
                       }
        }
   }

Here, we've written our own Optional factory, say, just because we don't like the name Optional::of.  That's allowed!  And we've written our own pattern to deconstruct a present optional. Everything here is static.

Now, we have a switch:

    switch (o) {
        case FriendOfOptional.presentOptional(var contents): ...
    }

How do we do this dispatch?
 - Let X be the static type of the operand
 - Perform "pattern overload selection" looking for FriendOfOptional::presentOptional
 - Type check arity and types of selected pattern
 - Note (from selected overload) that the target type of FOO::presentOptional is Optional<T>, call that Y  - Type check that X (type of switch target) is cast convertible to Y (pattern target) without an unchecked conversion  - If X is not a subtype of Y, insert an additional instanceof Y check in the case before trying to match to the FOO::presentOptional pattern (**)  - "Invoke" the pattern FOO::presentOptional with argument ((Y) o) if the pattern is static, or on receiver ((Y) o) if instance

All of this happens whether the pattern is an instance or static pattern; what differs is only (a) how we do overload selection (which has not been fully specified yet) and (b) how we pass the target to the pattern (receiver vs argument.)

Is it the ** part that is confusing you?

You have butchered my original email on that part, i was just saying that in term of linking all pattern methods (destructor, static pattern implemented using an instance method or a static methods), they all should be presented the same way for a user that want to declare them.

Then I'm going to ask that you be clearer on what you mean then! Because you started with a pile of "this is wrong, this doesn't work", which never helps, especially when it's not clear you've really understood what I'm shooting at first.  Maybe start with some clarifying questions about the parts you're fuzzy on?


Reply via email to