[swift-evolution] Remove Failable Initializers

Shawn Erickson shawnce at gmail.com
Tue Mar 8 16:17:13 CST 2016


On Tue, Mar 8, 2016 at 2:11 PM Shawn Erickson <shawnce at gmail.com> wrote:

> On Tue, Mar 8, 2016 at 1:19 PM Haravikk via swift-evolution <
> swift-evolution at swift.org> wrote:
>
>>
>> On 8 Mar 2016, at 15:26, Thorsten Seitz <tseitz42 at icloud.com> wrote:
>>
>> Am 08.03.2016 um 11:07 schrieb Haravikk via swift-evolution <
>> swift-evolution at swift.org>:
>>
>> Just because someone opts to use error handling over a failable
>> initialiser doesn’t mean they have to go overboard on the detail of their
>> errors; it’s entirely possible to pick a reasonable middle-ground.
>>
>>
>> And it is entitely possible to just use an optional. If you prefer to use
>> error handling over failable initializers, fine, just do so, but don't
>> force it on others who are perfectly happy with the option to use
>> optionals, too.
>>
>>
>> It’s not an issue of ideology but of redundancy; the failable initialiser
>> does nothing that error handling can’t do just as easily, the only
>> difference is that instead of returning nil, you throw an appropriate error.
>>
>> The few extra characters are hardly going to kill you, while a thrown
>> error (with common ones available for simplicity) can describe what went
>> wrong in more detail than just “something went wrong”. Point is that we
>> have two ways of achieving the same goal, but error handling encourages
>> developers to think more about what type(s) of error to throw at each
>> point; even just simple error types with no further detail can provide more
>> information simply by being different, for example if you have a
>> NonNumericError vs EmptyStringError types, the errors themselves tell you
>> all you’re likely to need to know (hopefully there’d be a good set of
>> common types).
>>
>> There are also some cases where failable initialisers can have subtle
>> errors, for example, can you tell me where I might run into problems with
>> the following:
>>
>> struct MyType {
>>     let elements:[String]
>>
>>     func asInt(index:Array<String>.Index) -> Int? {
>>         if self.elements.indices.contains(index) {
>>             return Int(self.elements[index])
>>         }
>>         return nil
>>     }
>> }
>>
>
> I assume you mean to imply the following...?
>
> let foo = MyType(elements: ["1", "2", "bogus", "4"])
> for i in 0..<5 {
>   if let value = foo.asInt(i) {
>     print( "Value[\(i)] = \(value)" )
>   }
>   else {
>     print( "Value[\(i)] = <no value>" )
>   }
> }
>
> Value[0] = 1
> Value[1] = 2
> Value[2] = <no value>
> Value[3] = 4
> Value[4] = <no value>
>
> When I see asInt(index) -> Int? I personally would only care about getting
> an Int back if possible for the given index then going on my merry way. If
> I was confused by something I would debug the problem. I likely wouldn't
> attempt to put any code in place to pick apart how it could have failed. If
> anything I would put in preconditions.
>
> If this API threw exceptions instead I would do that exact same thing.
>

I meant to also state I would design the API the following way since to me
a bad index is a logic bug that needs to fixed in the code.

struct MyType {
    let elements:[String]
    func asInt(index:Array<String>.Index) -> Int? {
        return Int(self.elements[index])
    }
}

let foo = MyType(elements: ["1", "2", "bogus", "4"])
for i in 0..<5 {
  if let value = foo.asInt(i) {
    print( "Value[\(i)] = \(value)" )
  }
  else {
    print( "Value[\(i)] = <no value>" )
  }
}

Value[0] = 1
Value[1] = 2
Value[2] = <no value>
Value[3] = 4
fatal error: Array index out of range
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160308/74fe2aed/attachment.html>


More information about the swift-evolution mailing list