[swift-evolution] Remove Failable Initializers

Haravikk swift-evolution at haravikk.me
Thu Mar 3 15:43:19 CST 2016

> On 3 Mar 2016, at 20:53, Félix Cloutier <felixcca at yahoo.ca> wrote:
> There are established guidelines for Swift error handling.

That’s fine, but this proposal would change that so I’m sure it’s really relevant. No one’s arguing that the current advice is bad, as it’s fine given that failable initialisers currently exist, but if they were to be removed then that advice simply needs to change.

> The guidance is that returning nil is appropriate when your function could fail due to simple domain errors, for instance passing a negative value as a parameter where they aren't allowed.

If that’s all you need then what’s wrong with throwing some generic purpose illegal argument type exception and using try? It’s functionally the same, i.e- removing failable initialisers doesn’t actually remove a capability, it just removes what is essentially now a redundant one. In other words, try? on a throwable initialiser is now functionally identical to a failable initialiser and isn't appreciably more complex, especially if there’s a common exception that can be thrown for general purpose invalid argument errors (not sure if there is one right now, but it could be added to the proposal).

That means we really have two identical features, one of which has greater flexibility, so does it make sense to keep the less capable variant?

> The duality is that an error reported through the throwing mechanism should be non-trivial.

Is calling an initialiser with invalid values really trivial?

> I am wary of using the try? keyword in general (as it discards potentially meaningful information) and I'm happy that initializers are allowed to be failable.

The difference between try? discarding potentially useful information and a failable initialiser is that the failable initialiser provides no potentially useful information. That to me is a reason against failable initialisers, as they’re simply providing a generic failure condition in the form of nil. Besides, I don’t think that try? has inherent problems, it explicitly indicates that you are aware that the initialiser can fail, and choose to ignore the actual error in favour of working with nil instead (or providing a default with ??). Sometimes the reason for something failing just doesn’t matter to you, only that it did fail.

That’s not to say that throwable initialisers can’t just return a single error type either; they absolutely can. The benefit of them over failable initialisers is that they could produce any number of useful errors depending upon what can actually go wrong.

More information about the swift-evolution mailing list