Rename "guard" to "unless"


(James Campbell) #1

What is "guard"? why its the opposite to "if"!

So in other languages what have they called this, well in Ruby they called
it "unless" which I feel is a much clearer form of intent and lower barrier
of entry for a user. See this code.

guard name != nil else {
   fatalError("Please enter a name")
}

What does that actually say if you look at it from a linguistic point of
view, "guard that name doesn't equal nil otherwise fail", that feels very
obtuse.

With my proposal the syntax could become this:

unless name != nil {
  fatalError("Please enter a name")
}

This now reads as "unless name doesn't equal nil then fail" which I think
is a much clearer syntax. I think this would be a great change for Swift 3.
For me I think this is more friendly for beginners.

It would support the same structure as an if block:

unless name != nil {
}
else
{
}

Going forward it would allow us to be more flexible if we added inline
if/unless statement, as in Ruby.

callThisMethod() if age > 0
throwThisError() unless age <= 0

···

--
 Wizard
james@supmenow.com
+44 7523 279 698


(Greg Parker) #2

`guard` is not the opposite of `if`. `guard` has effects that `if` does not. We deliberately chose not to provide syntax that was identical to `if not X`.

History: The very first proposal of this feature was called `unless`. Fifty-odd messages of discussion later it was called `require`, in part because we did not want to match the `if not` constructs seen in languages like Perl and Ruby. That name was still controversial. A few weeks later it was changed to `guard..else` to general acclaim because the intended use is commonly known as a "guard clause".

···

On Jan 6, 2016, at 2:09 AM, James Campbell via swift-evolution <swift-evolution@swift.org> wrote:

What is "guard"? why its the opposite to "if"!

So in other languages what have they called this, well in Ruby they called it "unless" which I feel is a much clearer form of intent and lower barrier of entry for a user. See this code.

guard name != nil else {
   fatalError("Please enter a name")
}

What does that actually say if you look at it from a linguistic point of view, "guard that name doesn't equal nil otherwise fail", that feels very obtuse.

With my proposal the syntax could become this:

unless name != nil {
  fatalError("Please enter a name")
}

This now reads as "unless name doesn't equal nil then fail" which I think is a much clearer syntax. I think this would be a great change for Swift 3. For me I think this is more friendly for beginners.

It would support the same structure as an if block:

unless name != nil {
}
else
{
}

Going forward it would allow us to be more flexible if we added inline if/unless statement, as in Ruby.

callThisMethod() if age > 0
throwThisError() unless age <= 0

--
Greg Parker gparker@apple.com Runtime Wrangler


(Scott Matthewman) #3

What is "guard"? why its the opposite to "if"!

Not exactly. It’s a guard clause, designed to be used at the beginning of a
method to ensure that certain conditions exist, and to exit early if they
do not.

In addition, guard in Swift works different to if in that any `let`
declarations made within the guard clause are set within the scope of the
parent method – especially useful if you need to unwrap optionals. With if,
they are only valid within the if block.

For example:

    if let name = optionalName as? Name {
      print(name) // okay
    }

    print(name) // out of scope

But with guard:

func printName(optionalName: Name?) {
  guard let name = optionalName else { return }

  print(name) // this is okay
}

So yes, the distinction is subtle – and in Ruby (the language I use in my
day to day work) we implement guard clauses with ‘if' or ‘unless’ blocks or
modifiers.

But with the difference in scope of assigned variables between `if` and
`guard` in Swift, I think your suggestion would make things slightly more
confusing, instead of slightly less.


(Johan K. Jensen) #4

What is "guard"? why its the opposite to "if"!

But it’s not.
guard’s else-clause requires you to transfer program control outside the
guard statement’s enclosing scope.
And any constants or variables assigned a value from an optional binding
declaration in a guard statement condition can be used for the rest of the
guard statement’s enclosing scope. That is what allows us to do `guard let
val = opt else { return }` where opt is an optional and val is the value
contained in opt if it is not nil.

Changing it to unless (and removing the else-clause) would only confuse
people coming from Ruby or similar languages, as they wouldn’t expect any
of the variable declarations to live in the guard statement’s enclosing
scope.

···

On Wed, Jan 6, 2016 at 11:09 AM, James Campbell via swift-evolution < swift-evolution@swift.org> wrote:

So in other languages what have they called this, well in Ruby they called
it "unless" which I feel is a much clearer form of intent and lower barrier
of entry for a user. See this code.

guard name != nil else {
   fatalError("Please enter a name")
}

What does that actually say if you look at it from a linguistic point of
view, "guard that name doesn't equal nil otherwise fail", that feels very
obtuse.

With my proposal the syntax could become this:

unless name != nil {
  fatalError("Please enter a name")
}

This now reads as "unless name doesn't equal nil then fail" which I think
is a much clearer syntax. I think this would be a great change for Swift 3.
For me I think this is more friendly for beginners.

It would support the same structure as an if block:

unless name != nil {
}
else
{
}

Going forward it would allow us to be more flexible if we added inline
if/unless statement, as in Ruby.

callThisMethod() if age > 0
throwThisError() unless age <= 0

--
 Wizard
james@supmenow.com
+44 7523 279 698

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


(Loïc Lecrenier) #5

Hi James,

“guard" is not the opposite of “if”.
From the Swift book: “You use a guard statement to require that a condition must be true in order for the code after the guard statement to be executed.”
So, unlike “unless”, a “guard" statement must provide an “early exit” in its else clause (fatalError, return, continue, break, …).
IMO, using “unless” would be less expressive, and encourage more misunderstanding of this feature.

Loïc

···

On Jan 6, 2016, at 11:09 AM, James Campbell via swift-evolution <swift-evolution@swift.org> wrote:

What is "guard"? why its the opposite to "if"!

So in other languages what have they called this, well in Ruby they called it "unless" which I feel is a much clearer form of intent and lower barrier of entry for a user. See this code.

guard name != nil else {
   fatalError("Please enter a name")
}

What does that actually say if you look at it from a linguistic point of view, "guard that name doesn't equal nil otherwise fail", that feels very obtuse.

With my proposal the syntax could become this:

unless name != nil {
  fatalError("Please enter a name")
}

This now reads as "unless name doesn't equal nil then fail" which I think is a much clearer syntax. I think this would be a great change for Swift 3. For me I think this is more friendly for beginners.

It would support the same structure as an if block:

unless name != nil {
}
else
{
}

Going forward it would allow us to be more flexible if we added inline if/unless statement, as in Ruby.

callThisMethod() if age > 0
throwThisError() unless age <= 0

--
 Wizard
james@supmenow.com
+44 7523 279 698
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(James Campbell) #6

Should we add this to the list of things requested that will be rejected ?

···

On Wed, Jan 6, 2016 at 10:58 AM, Greg Parker <gparker@apple.com> wrote:

> On Jan 6, 2016, at 2:09 AM, James Campbell via swift-evolution < > swift-evolution@swift.org> wrote:
>
> What is "guard"? why its the opposite to "if"!
>
> So in other languages what have they called this, well in Ruby they
called it "unless" which I feel is a much clearer form of intent and lower
barrier of entry for a user. See this code.
>
> guard name != nil else {
> fatalError("Please enter a name")
> }
>
> What does that actually say if you look at it from a linguistic point of
view, "guard that name doesn't equal nil otherwise fail", that feels very
obtuse.
>
> With my proposal the syntax could become this:
>
> unless name != nil {
> fatalError("Please enter a name")
> }
>
> This now reads as "unless name doesn't equal nil then fail" which I
think is a much clearer syntax. I think this would be a great change for
Swift 3. For me I think this is more friendly for beginners.
>
> It would support the same structure as an if block:
>
> unless name != nil {
> }
> else
> {
> }
>
> Going forward it would allow us to be more flexible if we added inline
if/unless statement, as in Ruby.
>
> callThisMethod() if age > 0
> throwThisError() unless age <= 0

`guard` is not the opposite of `if`. `guard` has effects that `if` does
not. We deliberately chose not to provide syntax that was identical to `if
not X`.

History: The very first proposal of this feature was called `unless`.
Fifty-odd messages of discussion later it was called `require`, in part
because we did not want to match the `if not` constructs seen in languages
like Perl and Ruby. That name was still controversial. A few weeks later it
was changed to `guard..else` to general acclaim because the intended use is
commonly known as a "guard clause".

--
Greg Parker gparker@apple.com Runtime Wrangler

--
 Wizard
james@supmenow.com
+44 7523 279 698


(Chris Lattner) #7

Should we add this to the list of things requested that will be rejected ?

Yes, if you send a good PR adding it, I’ll merge it. Note that it was (very briefly) named “unless” as a placeholder until May 1, 2015. We carefully bikeshedded this and settled on guard.

-Chris

···

On Jan 6, 2016, at 7:05 AM, James Campbell via swift-evolution <swift-evolution@swift.org> wrote:

On Wed, Jan 6, 2016 at 10:58 AM, Greg Parker <gparker@apple.com <mailto:gparker@apple.com>> wrote:

> On Jan 6, 2016, at 2:09 AM, James Campbell via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>
> What is "guard"? why its the opposite to "if"!
>
> So in other languages what have they called this, well in Ruby they called it "unless" which I feel is a much clearer form of intent and lower barrier of entry for a user. See this code.
>
> guard name != nil else {
> fatalError("Please enter a name")
> }
>
> What does that actually say if you look at it from a linguistic point of view, "guard that name doesn't equal nil otherwise fail", that feels very obtuse.
>
> With my proposal the syntax could become this:
>
> unless name != nil {
> fatalError("Please enter a name")
> }
>
> This now reads as "unless name doesn't equal nil then fail" which I think is a much clearer syntax. I think this would be a great change for Swift 3. For me I think this is more friendly for beginners.
>
> It would support the same structure as an if block:
>
> unless name != nil {
> }
> else
> {
> }
>
> Going forward it would allow us to be more flexible if we added inline if/unless statement, as in Ruby.
>
> callThisMethod() if age > 0
> throwThisError() unless age <= 0

`guard` is not the opposite of `if`. `guard` has effects that `if` does not. We deliberately chose not to provide syntax that was identical to `if not X`.

History: The very first proposal of this feature was called `unless`. Fifty-odd messages of discussion later it was called `require`, in part because we did not want to match the `if not` constructs seen in languages like Perl and Ruby. That name was still controversial. A few weeks later it was changed to `guard..else` to general acclaim because the intended use is commonly known as a "guard clause".

--
Greg Parker gparker@apple.com <mailto:gparker@apple.com> Runtime Wrangler

--
 Wizard
james@supmenow.com <mailto:james@supmenow.com>
+44 7523 279 698
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution