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

Vinicius Vendramini vinivendra at gmail.com
Wed Dec 16 16:15:02 CST 2015


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 <mailto: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 <mailto: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 <mailto: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 <mailto: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 <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>  _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>  _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution <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/2e247f1e/attachment.html>


More information about the swift-evolution mailing list