Well, the whole point was to make error handling syntax and semantics less 
magical and more generic-friendly, so you’re right, it is essentially a new sum 
type with error handling syntax on top of it.
Except, adding it alongside optional would introduce accidental complexity to 
swift’s “unexpected situations” mechanism.
It doesn’t have to be a massive source-break, since this pitch is supposed to 
be a strict superset of what Optional and throwing is currently.
The only thing that I can think of at this moment that would break is this 
syntax:

let foo: Int? = .none // Error: Can’t convert (Error) -> Int? to Int?

The ExpressibleByNilLiteral, the try/throw syntax, all of those things would 
work as they are right now.
Error handling as it is currently, is essentially a hidden `error` out 
parameter and a whole bunch of codegen.
Even the semantical changes described earlier would be purely additive.

> On Apr 30, 2017, at 8:35 PM, Robert Widmann <devteam.cod...@gmail.com> wrote:
> 
> This "revamp" is isomorphic to adding a Sum type to stdlib and plumbing error 
> handling syntax through.  I'd much rather see that than the massive 
> source-break this would entail.
> 
> ~Robert Widmann
> 
> 2017/04/30 13:11、Gor Gyolchanyan via swift-evolution 
> <swift-evolution@swift.org> のメッセージ:
> 
>> I’d like to suggest a bit of redesigning the Optional type and throwing 
>> functions to provide a single powerful and flexible mechanism for dealing 
>> with unexpected situations.
>> 
>> In short, The Optional would have an associated value of type Error added to 
>> its `none` case, which would describe the reason why the wrapped value is 
>> missing.
>> 
>> public enum Optional<Wrapped> {
>> 
>>   case .some(Wrapped)
>> 
>>   case .none(Error)
>> 
>> }
>> 
>> The Optional's ExpressibleByNilLiteral would initialize it with an error 
>> that corresponds to what is currently fatalError-ed as "unexpectedly found 
>> nil while unwrapping an Optional value".
>> 
>> The forced unwrapping operator (postfix `!`) would behave the same way as it 
>> does now, except in case of a fatal error it would print out the underlying 
>> error, instead of the aforementioned hard-coded string.
>> 
>> The optional chaining operator (postfix `?`) would behave the same way as it 
>> does now, except when it stops evaluating and returns the Optional, it would 
>> contain the error, returned by the sub-expression that failed to evaluate.
>> 
>> Any throwing function would be equivalent to a function that returns an 
>> Optional. If the function is declared as throwing and returning an Optional 
>> at the same time, it would be equivalent to a function returning an Optional 
>> Optional.
>> 
>> The if-let statement would bind the `let` variable to the wrapped value 
>> inside the "then" block and would bind it to the error in the "else" block. 
>> Chained else-if blocks would all be considered part of the overarching 
>> "else" block, so all of them would be able to access the error bound to the 
>> if-let name.
>> 
>> The guard-let and case-let statements are essentially just rewrites of 
>> if-let with some added logic.
>> 
>> The `try` keyword, applied to an optional would behave like this:
>> 
>> public func try<T>(_ optional: T?) throws -> T {
>>   guard let wrapped = optional else {
>>       throw wrapped // Remember, if-let, guard-let and case-let statements 
>> bind the let name to the error in case of a failure.
>>   }
>>   return wrapped
>> }
>> 
>> Multiple let bindings in a single if-let statement are essentially rewrites 
>> of a nested chain of if-let statements.
>> 
>> The `try` keyword applied to an optional would unwrap the value or throw the 
>> error.
>> The `try?` keyword applied to a throwing function call would cause any 
>> thrown errors to be caught and put into the returned Optional, instead of 
>> simply ignored.
>> The `try!` keyword applied to a throwing function call would behave as you'd 
>> expect: just like `try?` except immediately force-unwrapped.
>> 
>> A throwing function would be convertible to a non-throwing 
>> optional-returning function and vice versa.
>> This would allow making use of throwing functions when dealing with generics 
>> or protocols that allow arbitrary return types, without having to sacrifice 
>> the convenience of error-handling logic. Conversely, it would allow to write 
>> generic code that deals with any type of function without having to 
>> implement special cases for throwing functions. This means that the two 
>> function types would be interchangeable and one would be able to satisfy 
>> protocol requirements of the other. The `rethrows` idiom would then become a 
>> natural consequence of writing generic functions that may return optional 
>> and non-optional results just as well.
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution

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

Reply via email to