[External] : Re: Telling the totality story
Brian Goetz
brian.goetz at oracle.com
Fri Mar 4 02:23:58 UTC 2022
>
> #### Let
>
> This is where it gets ugly. Let has no opinions about null, but
> the game here is to pretend it does. So in a let statement:
>
> let P = e
>
> - Evaluate e
> - If e is null
> - If P is a covering pattern, its binding is bound to null;
> - else we throws NPE
> - Otherwise, e is matched to P. If it does not match (its
> remainder), a MatchException is thrown (or the else clause is
> taken, if one is present.)
>
>
> It's not clear to me why a MatchException should be thrown instead of
> not compiling if not exhaustive.
You're confusing "exhaustive" and "total". A let must be exhaustive,
but exhaustiveness != totality.
> It's mean that there are remainders that does not lead to either a NPE
> or an error, do you have an example of such remainder ?
Yes. Suppose we have records Box<T>(T t) and Pair<T, U>(T t, U u), and
A is sealed to B|C. Then if we're matching on a Pair<Box<A>, A>, then
Pair(null, B)
Pair(Box(B), D) // D is a type from the future
Pair(Box(D), B)
Pair(Box(D), D)
Pair(null, D)
are all in the remainder. It is a big stretch to claim either NPE or
ICCE is right for any of these, and completely arbitrary to pick one for
Pair(null, D). Also, its much more expensive to try to distinguish
between these, and pick the "right" error for each, rather than insert a
default clause that throws MatchRemainderException.
More information about the amber-spec-observers
mailing list