> func doSomething() throws → Result? { … }
> 
> How would you handle both the catch and the let binding of the result?

I agree this proposal needs to define the behavior, since returning an optional 
from a throwing function is valid.

I see a few options:

1) find a way to generally incorporate optional binding and error binding into 
the same guard clause.
Could it be as simple as 
guard let result:Result = try doSomething()
catch { ...}
else { ... }
?

 In this option, the else block almost acts like "finally" block.  I recommend 
against this option because IF the developer has defined a function which 
returns nil and doesn't throw an error, they clearly intend for the nil to be a 
valid representation of state, and thus one the developer may wish to examine 
in more detail and potentially continue the function. I. E. Let's give the 
developer a chance to work with the nil value and not return.

2) Ignore it completely.  I.e. define the guard/catch pattern as not compatible 
with returning Optionals.  Throwing an error is usually considered an 
alternative to returning an optional, and importing Obj-C won't import throwing 
methods in this way. So I don't think prohibiting it is a totally absurd idea.  
This makes it impossible for the developer to code and build code which 
accidentally does something he doesn't expect.

3) bind the optional value

Perhaps, when guard/catch-ing, an optional value is perfectly legal.

guard let result:Result? = try doSomething() catch ...
This is essentially how guard works with a try?today.
guard let result:Result? = try? doSomething() ...

In case 3, I think we have a potentially ambiguous behavior, because with type 
inference the programmer may expect that the value has also been optionally 
unwrapped.  Of course, he'll catch that later on in the function, but my 
concern is for the poor unwitting developer (such as myself) who is frustrated 
that his code doesn't compile and he doesn't understand why.  "But I did a 
guard let!   Why is it optional?!"  One option is to require the type be typed 
explicitly when guard/catching an optional, but I always type my types 
explicitly anyway, so I get that others may be more resistant to that idea.  
Another option is to allow it, but just issue a warning until the developer 
adds the explicit type, such as requiring "self." in an escaping closure.  (Of 
course the compler can figure it out, this syntax is required so the developer 
can figure it out!)  Another option is for the smarts to be built in the the 
error/warning system to point out when an expression gets used as a 
non-optional when it came from a guard/catch to point it out, much as it points 
out the first instance of a function which has been defined twice.


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

Reply via email to