#### 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.

Reply via email to