It seems like a complicated way to pretend you are not using goto while having semantics identical to goto. One advantage is that it is a block scope so if e.g. C++ had this, destructors could run, but this could also be supported with goto.
Does the following also have "semantics identical to goto"?
// functional lands
data EC = Situation1 | ... | SituationN
case (Expr0) of
Situation1 -> IOAction1
...
SituationN -> IOActionN
// imperative lands
type Outcome int
const Situation1 Outcome = iota, Situation2, ... SituationN
var outcome Outcome
for {
... { outcome = Situation1; break }
... { outcome = SituationN; break }
}
switch outcome {
case Situation1:
<statements1>
...
case SituationN:
<statementsN>
}
I personally don't think so, Zahn's construct is merely a way to succinctly express such a switch in the control flow. In fact, Rust almost has it, with its loops being expressions.
The semantics are much more restricted than goto. (a goto could always create a loop but situation indicators don't; a goto can jump between binding contours but situation indicators don't; etc.)
I think of it as an imperative way to pretend you're writing a tail-recursive nest with multiple base cases.