Revisiting the rule for merging type patterns ?

forax at univ-mlv.fr forax at univ-mlv.fr
Sun Aug 29 10:47:32 UTC 2021


> From: "John Rose" <john.r.rose at oracle.com>
> To: "Remi Forax" <forax at univ-mlv.fr>
> Cc: "amber-spec-experts" <amber-spec-experts at openjdk.java.net>
> Sent: Dimanche 29 Août 2021 03:25:26
> Subject: Re: Revisiting the rule for merging type patterns ?

> On Aug 28, 2021, at 2:42 PM, Remi Forax < [ mailto:forax at univ-mlv.fr |
> forax at univ-mlv.fr ] > wrote:

>> I think we should revisit that discussion and just not introduce the any
>> bindings in that case so the example above will compile but "literal" or
>> "funcall" are not added as local variable.

> Some partial comments:

> Allowing inconsistent/inaccessible binding names here
> as a particular workaround would be a sharp edge,
> since users would wonder where such a variable went,
> and why they can’t use it.

> I think this is really a feature-request for a type-only
> pattern (with no binding). And having “T _” is a fine way
> to bikeshed it.

> That said, the next feature request in that vein would be
> to allow variable-bindings (as today) for the sake of guard
> expressions, and then we are back to the problem you cite.

> Hmm… I guess the sharp edge has cause to stay, for the sake
> of guard logic like this:

> case Literal l && someGuard(l), FunCall f && someOtherGuard(f) -> …

> So I’m sympathetic with your request. It’s really about
> smuggling OR-expressions into switch-guards. Which isn’t
> terrible at first.

I see it as rehabilitating the OR-pattern. 
We use comma in between constants, we should be able to use comma in between patterns. 

I see a way to try to alleviate the issue of the inconsistent/inaccessible binding names, 
make the names available after the "->" but poison them so the names are accessible and/but javac emits a clear error message that those binding names are not available 
(we already does that in the initializer expression of a field). 

So 
case Literal literal && someGuard(literal), FunCall f && someOtherGuard(f) -> literal.foo() 

does not compile and javac can emit an error message on "literal.foo()" saying that binding names are not propagated through the OR-pattern. 

Obviously, it will still be weird the first time a user will try that but at least he will have an error message to google. 

> A third request in this vein is for combining bindings
> from arms of an OR-expression. That’s when it gets
> more terrible:

> case Literal lorf && decon1(l, n), FunCall lorf && decon2(f, n) -> {
> lorf is an intersection type, and maybe n is int
> if decon1/2 collude to make it so
> }

> Assembling one binding from several OR-branches
> seems to be a requitable feature, but one that would
> be really hard to make rational and predictable.

An intersection type is not very useful because you can only call methods that are available on a common super-type, 
so this is equivalent to 
case CommonSuperTypeOfLiteralAndFunCall lorf && decon3(lorf, n) -> ... 

It would be different if Java had a real way to OR types like Scala 3 (and Ceylon before). 

> — John

Rémi 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20210829/ecf22446/attachment-0001.htm>


More information about the amber-spec-experts mailing list