Intersection types in patterns

Mark Raynsford mark at io7m.com
Sat Oct 20 16:56:39 UTC 2018


On 2018-10-20T12:42:42 -0400
Brian Goetz <brian.goetz at oracle.com> wrote:
> > Is there a situation where you could have reached that case without
> > having a reference to p? If I've understood so far:
> > 
> >  SomeSuperTypeOfPoint q;
> > 
> >  switch (q) {
> >    case Point(var x, var y) p: ... // p == q and p : Point
> >  }  
> 
> Yes, you could have gotten there via
> 
>     switch (getAnObjectForMe()) { 
>         case Point(var x, var y) p: 
>     }

That is a good point!

> > So in the Point case there, you could do something with the fields
> > x, y  
> 
> Careful, binding variables — they may be copied from fields, but we don’t know that.  Deconstruction patterns are really like methods that conditionally return multiple values; but methods don’t have to read fields to return a value.

Right.

> > How is the resulting declaration scoped? What if I do...
> > 
> >  SomeSuperTypeOfPoint q;
> > 
> >  switch (q) {
> >    case Point(var x, var y) p:      ... // p == q and p : Point
> >    case OtherPoint(var x, var y) p: ... // p == q and p : OtherPoint
> >  }  
> 
> This is well handled by the flow-scoping rules (and one of the reasons we chose such a scoping). 

Yes, that's what I suspected.

>  So the first p is in scope for the statements that follow the first
>  case, and similar for the second.  If you fall through from the first
>  to the second, then there are competing overlapping definitions of
>  `p`, and you get an error.  So scoping is not a reason not to do this
>  (you could have collisions on x and y too, which would be handled by
>  the same set of rules), but I think what you’re getting at here is “I
>  don’t see how its needed, you can always pull the switch target into a
>  variable, and cast it.”  

Right, I'm up to speed. I retract my con!

-- 
Mark Raynsford | http://www.io7m.com



More information about the amber-spec-experts mailing list