> On Mar 16, 2018, at 5:39 AM, Peter Levart <peter.lev...@gmail.com> wrote: > > Expanding on do…
Well, as long as we are fantasizing: > On 03/16/18 09:50, Peter Levart wrote: >> And if "while (false)" could be optional, we get: > > Or better yet, make "while (true)" optional even in statement do, so we can > finally get away with some more boilerplate: > > for (;;) { > } > > or > > while (true) { > } > > and simply do: > > do { > } > > For e-do, the choice of default "while (true)" is fine, because it aligns > with the fact that there has to be a break <value> somewhere to exit it > anyway because it has to yield a result. But there will be some danger that a > programmer codes an infinite loop by mistake. This idea of making “while(true)” be the default has made me realize that Java has excellent syntactic space available to support a style of programming that was mildly popular in the late 1970s and early 1980s: Dijkstra’s “guarded commands” as described in his 1976 book “A Discipline of Programming”. It’s a beautifully concise and symmetric theory of control structure, provided that you have committed to a style of programming entirely centered around assignment statements (which explains why it has largely fallen by the wayside). Consider the following tale a trip down memory lane to an alternate universe: <fantasy serious=“FALSE"> ______________________________________________________________________________ Let a guarded command in Java have this form: case booleanExpression: statement* (Dijkstra used the form “booleanExpression -> statement*”. It’s more Java-like to use the keyword `case` and a colon.) ______________________________________________________________________________ First, we define a statement form of do: do { <guarded-command>* } The semantics are: evaluate the guards of all the guarded commands; if none is true, then terminate, else nondeterministically choose some command whose guard was true, execute its statements, and then repeat this process. It can be syntactically distinguished from the existing `do` statement in two ways: it contains guarded commands rather than simple statements, and there is no `while (expression)` at the end. Example: { int j = 0; do { case j < n: a[j] = f(j); ++j; } } ______________________________________________________________________________ Corresponding to that is a statement form of `if`: if { <guarded-command>* } The semantics are: evaluate the guards of all the guarded commands; if none is true, then abort (program error), else nondeterministically choose some command whose guard was true and execute its statements. It can be syntactically distinguished from the existing `if` statement because there is a left-brace after the keyword `if`. Example: if { case x <= 0: a = -b; case x >= 0: a = b; } ______________________________________________________________________________ Now, to make expression forms of these puppies (something Dijkstra never envisioned), we need a way to yield values. For an `if`, we just use `break`: int a = if { case x <= 0: break -b; case x >= 0: break b; }; ______________________________________________________________________________ In the same manner as for `switch`, we can abbreviate `: break` as `->`: int a = if { case x <= 0 -> -b; case x >= 0 -> b; }; This feels very much like an expression switch, but with choices made by boolean expressions rather than a switch value. ______________________________________________________________________________ Now, the expression form of `do` is a bit trickier, because the `do` terminates only when no guard is true, so the return value cannot be specified in any of the contained statements. The “obvious” answer is: do { <guarded-command>* } break expression and at this point everyone else on this mailing list breaks out the torches and pitchforks to come after me. :-) ______________________________________________________________________________ </fantasy> —Guy P.S. “Did you succeed in using your time machine to get guarded commands into Java?” “Yes, but in a past that hasn’t happened yet—it’s complicated.” (Tip of the hat to Norm Feuti.)