Intersection types in patterns

Brian Goetz brian.goetz at
Sat Oct 20 15:40:39 UTC 2018

Here's a question regarding the pattern grammar.  We anticipate:

     Type patterns:            TypeName[?] bindingName
     Constant patterns:        StringLiteral | NumericLiteral | Identifier
     Deconstruction patterns:  TypeName(Pattern*)
     Any patterns:             var bindingName | "_"

Note that we are fairly rigid here about binding variables; constant and 
underscore-any patterns _cannot_ have them, type and var-any patterns 
_must_ have them.

One area where we have a question about whether to support an optional 
binding variable is in deconstruction patterns:

     case Point(var x, var y) p: ...

Sometimes it is desirable to bind the cast target as well as its 
components (Scala and Haskell support this with the `var at pattern` 
syntax.)  Can anyone offer pros/cons here for supporting this based in 
real-world experience?  (Assume someone has already said "I could 
imagine how that might be useful.")

On 10/20/2018 1:58 AM, Tagir Valeev wrote:
> Hello!
> It seems that sometimes it could be useful to have intersection types
> in patterns. Assuming
> interface Foo { void foo(); }
> interface Bar { void bar(); }
> one might want to match `obj instanceof (Foo & Bar) foobar` to be able
> to call both `foo()` and `bar()`. After all we can now declare `var
> foobar = (Foo & Bar) obj`.
> Another interesting case is when LHO of matching operator is not
> assignable from pattern type. Like `if (getFoo() instanceof Bar bar) {
>;; }`. We know that getFoo() returns Foo, thus bar
> is Foo as well. Probably it's type could be narrowed to the (Foo &
> Bar) intersection automatically.
> I'm not sure whether there are many usecases for this, but probably it
> worth exploring.
> With best regards,
> Tagir Valeev.

More information about the amber-spec-experts mailing list