Failable Initializer Suggestion


#1

Hello.

I just found that the design of failable initializer is redundant in Swift 2. Because native error handling already has been introduced in Swift 2, and failable initializer indeed could be achieved by following codes:

  class AClass {
    init() throws {
      // initialize and throw error when failed
    }
  }

  let anInstance = try? AClass()

And you can get the reason why the initialization was failed to guide your following recovering by using codes below, which is not able to be done with failable initializer:

  do {
    let anInstance = try AClass()
  } catch let error {
    // recover from the error
  }

Probably the heaviest impact to current code done by removing failable initializer is the consequential changes of NSCoding protocol’s designated initializer.

As NSCoding protocol defines a designated initializer which unarchives the object graph from the archived data which could be invalid (by a wrong treating during a previous encoding), expired (by a software upgrade) or corrupted (by a disk error or user corrupting), the initialization might be failed respectively. But according the Objective-C’s design, such a failure is implicit and no error info would be thrown. So for NSCoding defined initializers implemented in Objective-C, it should add a default error to them when bridging them to Swift if the failable initializer was removed and the designated initializer in NSCoding was re-defined with an initializer throws error info.

How do you guys think of that?

Thanks for reading.

WeZZard


(Chris Lattner) #2

I’d be opposed to removing failable initializers. Failable inits introduce a symmetry into the language for initializers, which make them possible to do (almost) all of what you can do with a normal method. This capability is key for them to be able to replace “factory” static methods, which allows Swift to offer a consistent initialization pattern for clients of types.

If we forced people to use error handling for anything that could return nil, then things like String to Int conversions would most likely not use initialization syntax.

Besides that, over use of error handling waters it down and makes it less valuable in itself. For more information on this, please see the design discussion for error handling:

-Chris

···

On Dec 27, 2015, at 5:22 AM, Manfred Lau via swift-evolution <swift-evolution@swift.org> wrote:

I just found that the design of failable initializer is redundant in Swift 2. Because native error handling already has been introduced in Swift 2, and failable initializer indeed could be achieved by following codes:


(Tino) #3

How do you guys think of that?

Makes sense.
Failable init has its roots in Objective-C, throws is a better fit for Swift — but it is not trivial to change all Cocoa class to throw instead of returning nil (at least in theory — most likely many classes don't have that many reasons for a possible error).
Imho failable init should be removed again (but in a timeframe beyond the normal range of this list :wink:

Tino


(Thorsten Seitz) #4

+1 for keeping failable initializers. Error handling should be reserved for errors and not be used for control flow or logic.

-Thorsten

···

Am 27.12.2015 um 18:11 schrieb Chris Lattner via swift-evolution <swift-evolution@swift.org>:

On Dec 27, 2015, at 5:22 AM, Manfred Lau via swift-evolution <swift-evolution@swift.org> wrote:
I just found that the design of failable initializer is redundant in Swift 2. Because native error handling already has been introduced in Swift 2, and failable initializer indeed could be achieved by following codes:

I’d be opposed to removing failable initializers. Failable inits introduce a symmetry into the language for initializers, which make them possible to do (almost) all of what you can do with a normal method. This capability is key for them to be able to replace “factory” static methods, which allows Swift to offer a consistent initialization pattern for clients of types.

If we forced people to use error handling for anything that could return nil, then things like String to Int conversions would most likely not use initialization syntax.

Besides that, over use of error handling waters it down and makes it less valuable in itself. For more information on this, please see the design discussion for error handling:
https://github.com/apple/swift/blob/master/docs/ErrorHandlingRationale.rst

-Chris

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


(Dennis Lysenko) #5

My initial stance several months ago was that initializers should throw
instead of returning nil, but I've changed it as a result of the error
handling rationale (same document as Chris linked).

Specifically this section, taken from ErrorHandlingRationale.rst:

Simple domain errors

A simple domain error is something like calling String.toInt() on a string
that isn't an integer. The operation has an obvious precondition about its
arguments, but it's useful to be able to pass other values to test whether
they're okay. The client will often handle the error immediately.

Conditions like this are best modeled with an optional return value. They
don't benefit from a more complex error-handling model, and using one would
make common code unnecessarily awkward. For example, speculatively trying
to parse aString as an integer in Java requires catching an exception,
which is far more syntactically heavyweight (and inefficient without
optimization).

Because Swift already has good support for optionals, these conditions do
not need to be a focus of this proposal.

In constructors, the most common (and I would posit the only common) case
of error would be a simple domain error, so failable initializers suffice.

···

On Tue, Jan 5, 2016 at 12:52 AM Thorsten Seitz via swift-evolution < swift-evolution@swift.org> wrote:

+1 for keeping failable initializers. Error handling should be reserved
for errors and not be used for control flow or logic.

-Thorsten

Am 27.12.2015 um 18:11 schrieb Chris Lattner via swift-evolution < > swift-evolution@swift.org>:

On Dec 27, 2015, at 5:22 AM, Manfred Lau via swift-evolution < > swift-evolution@swift.org> wrote:

I just found that the design of failable initializer is redundant in Swift
2. Because native error handling already has been introduced in Swift 2,
and failable initializer indeed could be achieved by following codes:

I’d be opposed to removing failable initializers. Failable inits
introduce a symmetry into the language for initializers, which make them
possible to do (almost) all of what you can do with a normal method. This
capability is key for them to be able to replace “factory” static methods,
which allows Swift to offer a consistent initialization pattern for clients
of types.

If we forced people to use error handling for anything that could return
nil, then things like String to Int conversions would most likely not use
initialization syntax.

Besides that, over use of error handling waters it down and makes it less
valuable in itself. For more information on this, please see the design
discussion for error handling:
https://github.com/apple/swift/blob/master/docs/ErrorHandlingRationale.rst

-Chris

_______________________________________________
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