The "guard" keyword, again


(Dave Yost) #1

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.


(Sean Heber) #2

In the Commonly Rejected Changes page and in this swift-evolution email 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”.

FYI the decisions and discussions that lead to “guard" occurred within Apple well before Swift was open sourced.

l8r
Sean


(Rimantas Liubertas) #3

In summary, “require … else” is a very clean choice and beats “guard ...
else” handily.

For you maybe. I prefer quard—it carries slightly different semantic load
and fits more cases, imho.

r.


(James Campbell) #4

I think unless has always made more sense, guard felt like a multithreaded
statement as in guard this variable from other threads.

···

*___________________________________*

*James⎥Head of Trolls*

*james@supmenow.com <james@supmenow.com>⎥supmenow.com <http://supmenow.com>*

*Sup*

*Runway East *

*10 Finsbury Square*

*London*

* EC2A 1AF *

On 21 June 2016 at 09:14, Rimantas Liubertas via swift-evolution < swift-evolution@swift.org> wrote:

In summary, “require … else” is a very clean choice and beats “guard ...

else” handily.

For you maybe. I prefer quard—it carries slightly different semantic load
and fits more cases, imho.

r.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Chris Lattner) #5

Correct. There is no publicly released Swift version that used ‘unless’, but you can see it appear in the changelog.

-Chris

···

On Jun 21, 2016, at 6:44 AM, Sean Heber via swift-evolution <swift-evolution@swift.org> wrote:

In the Commonly Rejected Changes page and in this swift-evolution email 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”.

FYI the decisions and discussions that lead to “guard" occurred within Apple well before Swift was open sourced.


(Leonardo Pessoa) #6

Perhaps that was the original idea (guard as a multithreaded statement)
since in iOS your code and the UI run on different threads. Anyway, I'd
still stick with guard as I don't think this is confusing enough to justify
a change.

···

On Tuesday, 21 June 2016, James Campbell via swift-evolution < swift-evolution@swift.org <javascript:_e(%7B%7D,'cvml','swift-evolution@swift.org');>> wrote:

I think unless has always made more sense, guard felt like a multithreaded
statement as in guard this variable from other threads.

*___________________________________*

*James⎥Head of Trolls*

*james@supmenow.com⎥supmenow.com <http://supmenow.com>*

*Sup*

*Runway East *

*10 Finsbury Square*

*London*

* EC2A 1AF *

On 21 June 2016 at 09:14, Rimantas Liubertas via swift-evolution < > swift-evolution@swift.org> wrote:

In summary, “require … else” is a very clean choice and beats “guard ...

else” handily.

For you maybe. I prefer quard—it carries slightly different semantic load
and fits more cases, imho.

r.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
L