[swift-evolution] [Pitch] Guarding on enum values

Félix Cloutier felixcca at yahoo.ca
Thu Dec 24 08:37:36 CST 2015


I like that it's consistent with the if syntax (even though I don't really like the if syntax) and that there's no dangling parts after the else.

Félix

> Le 24 déc. 2015 à 06:29:17, Thorsten Seitz via swift-evolution <swift-evolution at swift.org> a écrit :
> 
> What do you think of
> 
> guard let r = returnsResult(), case let .Succeed(m) = r else {
>        return r 
> }
> 
> Which binds r only within the scope of the guard as desired.
> 
> Written in multiple lines
> 
> guard 
>        let r = returnsResult(), 
>        case let .Succeed(m) = r 
> else {
>        return r 
> }
> 
> -Thorsten 
> 
>> Am 24.12.2015 um 01:02 schrieb Andrew Duncan via swift-evolution <swift-evolution at swift.org>:
>> 
>> Yes, which would revert to Brent’s suggestion. But you have generalized it in a very compatible way.
>> 
>> As I read somewhere, improving programming languages comes from removing limitations rather than adding features. I intend for this Pitch to be the former, although it does kind of look like the latter.
>> 
>>> On 23 Dec, 2015, at 15:58, Joe Groff <jgroff at apple.com> wrote:
>>> 
>>> 
>>>> On Dec 23, 2015, at 3:56 PM, Andrew Duncan <andrewzboard at gmail.com> wrote:
>>>> 
>>>> More progress! This sounds good, but it looks like what you intend is for r to be the error message in the Result enum type.
>>>> 
>>>> enum Result {
>>>> case .Fail(String)    // Error message
>>>> case .Succeed(MyType) // Something to work with
>>>> }
>>>> 
>>>> guard case let .Succeed(m) = returnsResult() else case let .Failure(r) {
>>>>   return r // Looks like r is bound to the error String. 
>>>>            // But maybe you meant r = the entire returnsResult() result.
>>>> }
>>> 
>>> I see. If it's an arbitrary pattern, you can match 'case let r' to bind the entire value instead of picking out the payload of the other case. That would still be exhaustive.
>>> 
>>> -Joe
>>> 
>>>> 
>>>> The sort of message-passing error-handling I have in mind is where each method in the call chain returns a full Result enum and each stage checks it for Succeed/Fail, and immediately bails on Fail, returning (propagating) the Result. To be sure, this is sort of what exceptions do under the hood anyway.
>>>> 
>>>> My use-case is a recursive descent parser that I want to bail when a syntax error is found. This could happen way deep in the stack of calls. If I consistently return a .Fail(ErrorCode) or .Succeed(ASTNode) from each method, I just pass on the Result in case of .Fail, or use it in case of .Succeed.
>>>> 
>>>> 
>>>>> On 23 Dec, 2015, at 15:35, Joe Groff <jgroff at apple.com> wrote:
>>>>> 
>>>>> 
>>>>>> On Dec 23, 2015, at 10:16 AM, Andrew Duncan via swift-evolution <swift-evolution at swift.org> wrote:
>>>>> 
>>>>> A slight generalization would be to allow for an arbitrary pattern in the `else` clause:
>>>>> 
>>>>> guard case let .Succeed(m) = returnsResult() else case let .Failure(r) {
>>>>>   return r
>>>>> }
>>>>> 
>>>>> with the requirement that the "guard" and "else" patterns form an exhaustive match when taken together. That feels nicer than special-case knowledge of two-case enums, though I admit it punishes what's likely to be a common case.
>>>>> 
>>>>> -Joe
>> 
>> _______________________________________________
>> 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



More information about the swift-evolution mailing list