> From: "Brian Goetz" <brian.go...@oracle.com> > To: "Remi Forax" <fo...@univ-mlv.fr> > Cc: "amber-spec-experts" <amber-spec-experts@openjdk.java.net> > Sent: Wednesday, February 16, 2022 3:57:39 PM > Subject: Re: [External] : Re: Reviewing feedback on patterns in switch
> 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 :) I think it's wiser to delay the discussion about let for later :) RĂ©mi > 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.