In the Commonly Rejected Changes
<https://github.com/apple/swift-evolution/blob/master/commonly_proposed.md>
page and in this swift-evolution email
<https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160104/005534.html>
to which it refers, I read that first there was “unless", then “require” then
finally “guard ... else”.
I couldn’t find the earlier discussion in which “unless” was replaced for a
while by “require”, so I am moved to ask, “Was there ever “require … else”, or
was it just “require”? I’ll assume it was just “require”.
There are various problems with the choice of the keyword “guard”. These have
bothered me every since I first saw it.
Problems:
If we’re reading “guard” as a verb, then we expect the object to come right
after it, but it doesn’t; you can’t say you’re guarding the condition-clause.
No, what you’re guarding is the code after the entire guard-statement.
The “else” after guard suggests that the else code covers what to do when the
guard fails, but the guard doesn’t fail in the “else”; the guarding works
correctly on both execution paths.
The “guard” keyword gives no hint really as to whether the condition is
required or prohibited; you figure that out only be thinking about why there is
an “else” clause. The guard statement is intended to replace typical code in
the wild that uses an “if” statement that is written to abort when the
condition fails, not when it succeeds.
Proposed
require count >= 0 else { return }
Replaces
guard count >= 0 else { return }
Unambiguously equivalent to
if count < 0 { return }
Benefits of “require … else”:
The word “require” states more clearly and strongly than “guard” that it is an
ultimatum.
The word “require” conveys clearly that the require-statement can block the
following statement from executing.
The condition-clause functions as the object of the verb “require”, so it reads
well as natural language.
The sense of the condition-clause is clear; success is required before
executing the next statement.
The “else” after “require” clearly introduces code to run if the requirement is
not met.
With the new comma syntax for conditions, the word “require” fits well with the
fact that all conditions in the list are, shall we say, required.
When one of the conditions is a let, “require” conveys the idea that the
declaration will be required and thus will have a lifetime beyond the
require-statement.
It would still be OK to refer to a require-statement as a “guard clause", to
invoke the history of guarding. But even here, I think “require clause” is
clearer (see last bullet point). Evoking the historical use of the term “guard”
for this construct in Swift is not such a great argument because (a) the term
is not that well known, and (b) the term has not always been used for clearly
the same purpose. Dijkstra’s use of the term
<https://en.wikipedia.org/wiki/Guarded_Command_Language#Selection:_if>, for
example, was a bit different, allowing for nondeterministic execution.
In summary, “require … else” is a very clean choice and beats “guard ... else”
handily.
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution