OK, I'll make you a deal: I'll answer your question about let/bind, under the condition that we not divert the discussion on that right now -- there'll be a proper writeup soon.  The answer here is entirely for context.

If you don't agree, stop reading now :)

On 2/15/2022 5:58 PM, Remi Forax wrote:

     - There are future constructs that may take patterns, and may (or
    may not) want to express guard-like behavior, such as `let`
    statements (e.g., let .. when .. else.)  Expressing guards here
    with && is even less evocative of "guard condition" than it is
    with switches.


It's not clear to me how to use "let when else". Is it more like a ?: in C than the let in in Caml ?

The simplest form of `let` is a statement that takes a total pattern:

    let Point(var x, var y) = aPoint;

and introduces bindings x and y into the remainder of the block. When applicable, this is better than a conditional context because (a) you get type checking for totality, and (b) you don't indent the rest of your method inside a test that you know will always succeed.

If the pattern is total but has some remainder, the construct must throw on the remainder, to preserve the invariant that when a `let` statement completes normally, all bindings are DA.

What if I want to use a partial pattern, and then customize either the throwing part or provide default values?   I can provide an else clause:

    Object o = ...
    let String s = o
    else throw new NotStringException();

or

    Object o = ...
    let String s = o
    else { s = "no string"; }

These are two ways to preserve the "DA on normal completion" invariant; either by not completing normally, or by ensuring the bindings are DA.

Now, we are in a situation where we are with switch: patterns do not express all possible conditions.  Which is why we introduced guards to switches.  And we can use the same trick here:

    Object o = ...
    let String s = o
    when (!s.isEmpty())
    else { s = "no string"; }

If we tried to use && here, it would look like

    Object o = ...
    let String s = o && (!s.isEmpty())
    else { s = "no string"; }

which has the same problem as `case false && false`.

Reminder: THIS EXPLANATION WAS PROVIDED SOLELY TO CLARIFY THE "FUTURE CONSTRUCT" COMMENT IN THE && DISCUSSION.

Reply via email to