[swift-evolution] Proposal: Add implicit/default else-behaviour for the guard statement

Stephen Celis stephen.celis at gmail.com
Wed Dec 16 17:26:10 CST 2015


I'm opposed. I don't think `else { return }` is enough of a mouthful to add
a default behavior that must be learned and reasoned with.

Stephen

On Wed, Dec 16, 2015 at 5:36 PM, Vester Gottfried via swift-evolution <
swift-evolution at swift.org> wrote:

> I just skipped through 200+ guard statements that return Void, nil or a
> value and no statement was inside a scope that can be exited with break.
>
> I am also thinking about the proposals regarding default values to return,
> but I am not sure if this would even be necessary.  In my case 80% of all
> guard statements end with "else { return }" or "else { return nil }".
>
> On Wed, Dec 16, 2015 at 11:20 PM, Etan Kissling via swift-evolution <
> swift-evolution at swift.org> wrote:
>
>> If guard defaults to something context-dependent, it's also
>> counterintuitive.
>>
>>
>> Me personally is fine with guard x > 0 returning from the function in
>> this case.
>>
>> I use guard mainly as a glorified assert that allows safe exit from the
>> function instead of crashing the program on fail.
>> If you think about it that way, it's perfectly reasonable that it returns
>> in all cases.
>>
>>
>>
>> On the other hand, the implicit default else behaviour could only trigger
>> if there is no outer scope that can be exited with break.
>> Maybe OP could post additional statistics of the number cases where
>> "guard ... else { return }" is used inside a breakable scope.
>>
>>
>> Etan
>>
>>
>>
>>
>>
>> On 16 Dec 2015, at 23:15, Vinicius Vendramini <vinivendra at gmail.com>
>> wrote:
>>
>> Bringing up a possible edge case:
>>
>> func foo() {
>>     while(…) {
>>         guard x > 0
>>     }
>> }
>>
>> if guard defaulted to return even inside a while (as was suggested), this
>> might be counterintuitive.
>>
>> On Dec 16, 2015, at 5:06 PM, Etan Kissling via swift-evolution <
>> swift-evolution at swift.org> wrote:
>>
>> Also +1 on default return, -1 on default continue / break, and -1 for
>> removing braces
>>
>> Instead of VoidLiteralConvertible, one could extend on the idea with
>> something that is not specifically tailored to nil, like
>>
>> func foo(x: Int) -> Int = 5 {
>>     guard x < 10 // Would return default 5 for x >= 10
>>
>>     if x > 5 {
>>         return // Would return default 5
>>     }
>>     return x
>> }
>>
>>
>>
>> Etan
>>
>>
>> On 16 Dec 2015, at 19:39, Ian Ynda-Hummel via swift-evolution <
>> swift-evolution at swift.org> wrote:
>>
>> I am also +1 for implicit return, but -1 on continue/break for the
>> reasons already stated.
>>
>> I'm -1 for removing braces for one-liners. I think maintaining braces
>> around blocks helps distinguish them from expressions. For example,
>>
>>     guard x < 10 else return
>>
>> would catch me off guard (pardon the pun).
>>
>> I think I'm -1 on VoidLiteralConvertible, but I'm somewhat undecided. I
>> think that separating the return value from the actual return point could
>> lead to a lot of confusion, and would subsequently also make it easy to
>> accidentally return the default value when you didn't intend to as the
>> compiler wouldn't complain about a missing return value.  I don't think I
>> have totally convinced myself that the latter is a non-trivial problem, but
>> I thought it was worth mentioning.
>>
>> On Wed, Dec 16, 2015 at 11:59 AM ilya via swift-evolution <
>> swift-evolution at swift.org> wrote:
>>
>>> Actually I thought about VoidLiteralConvertible some more and now I
>>> think if we include it the only nontrivial case in the standard library
>>> case should be Optional.Nonel. Empty arrays and dictionaries are different
>>> from nothing, so it's best to always return them explicitly.
>>>
>>> Oh, and it would help with default values, e.g.
>>>
>>> var something:Something?
>>> // where does the default value come from? VoidLiteralConvertible!
>>>
>>> I want all default values for String in this scope be "none":
>>>
>>> private extension String: VoidLiteralConvertible { ... return "None" ...
>>> }
>>>
>>> On Wed, Dec 16, 2015 at 10:49 ilya <ilya.nikokoshev at gmail.com> wrote:
>>>
>>>> +1 on default return
>>>>
>>>> -1 on default continue or break, this is ambiguous.
>>>> Even inside switch it's not clear if guard should break or return, so
>>>> let's not make people guess. .
>>>>
>>>> Also can we stop requiring braces for simple one-liners:
>>>>
>>>> guard x<10 else return 5
>>>>
>>>> As for default return values, we could create a VoidLiteralConvertible,
>>>> so that default return automatically becomes return nil or return [] in an
>>>> Optional or Array context respectively. As a bonus, it will be technically
>>>> possible to override this behavior inside a specific function scope.
>>>>
>>>> > swift would provide a warning that the guard statement needs an else
>>>> block
>>>>
>>>> In this specific case the compiler basically has to guess, so an error
>>>> seems more appropriate.
>>>>
>>>> Ilya.
>>>>
>>>> On Wed, Dec 16, 2015 at 02:53 Vester Gottfried via swift-evolution <
>>>> swift-evolution at swift.org> wrote:
>>>>
>>>>> I find myself writing the same else blocks for guard statements over
>>>>> and over again, so it might be reasonable to think about a default
>>>>> behaviour.
>>>>>
>>>>> In a current project I found 217 guard statements from which 183 have
>>>>> repetitive else clauses
>>>>>
>>>>> From which:
>>>>> 131 end with "else { return nil }"
>>>>> 44 "else { return }"
>>>>> 6 "else { continue }"
>>>>> 2 "else { break }"
>>>>>
>>>>> My proposal would be to make the else block optional and define a
>>>>> default behaviour.
>>>>>
>>>>> For example:
>>>>>
>>>>> func foo(x: Int) {
>>>>> ​    ​
>>>>> guard x < 10
>>>>> ​    ​
>>>>> ...
>>>>> }
>>>>>
>>>>> swift would implicitly add "else { return }"
>>>>>
>>>>> --
>>>>>
>>>>> func foo(x: Int) -> Int? {
>>>>> ​    ​
>>>>> guard x < 10
>>>>> ​    ​
>>>>> ...
>>>>> }
>>>>>
>>>>> swift would implicitly add "else { return nil }"
>>>>>
>>>>> --
>>>>>
>>>>> for i in 0..<10 {
>>>>> ​    ​
>>>>> guard i%2 == 0
>>>>> }
>>>>>
>>>>> swift would implicitly add "else { continue }"
>>>>>
>>>>> --
>>>>>
>>>>> switch {
>>>>> case a :
>>>>> ​    ​
>>>>> guard x != y
>>>>> case b :
>>>>> ​    ...​
>>>>>
>>>>> }
>>>>>
>>>>> swift would implicitly add "else { break }"
>>>>>
>>>>> --
>>>>>
>>>>> func foo(x: Int) -> Int {
>>>>> ​    ​
>>>>> guard x < 10
>>>>> ​    ​
>>>>> ...
>>>>> }
>>>>>
>>>>> swift would provide a warning that the guard statement needs an else
>>>>> block
>>>>>
>>>>> --
>>>>>
>>>>> Possible advantages
>>>>> - Less code
>>>>> ​ to write​
>>>>>
>>>>> - visually cleaner
>>>>> -
>>>>> ​ ​
>>>>> In code with multiple guard statements
>>>>> ​ ​
>>>>> you
>>>>> ​ ​
>>>>> would not have to repeat the else block
>>>>>
>>>>>
>>>>> Possible Disadvantages
>>>>> - Different behaviour in different contexts (func/return,
>>>>> for/continue, switch/break, …) needs to be learned and understood
>>>>> - programmers might forget that guard + else {} is an option
>>>>>  _______________________________________________
>>>>> swift-evolution mailing list
>>>>> swift-evolution at swift.org
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>>
>>>>  _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>
>>  _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>>
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151216/e3778243/attachment.html>


More information about the swift-evolution mailing list