[swift-evolution] Remove Failable Initializers
Gwendal Roué
gwendal.roue at gmail.com
Mon Mar 7 13:04:12 CST 2016
I like the alternative, which makes it clear, at the call site, that the initializer is failable:
> An alternative is to change the falliable initiliser to have the optional symbol required at the call-site:
>
> MyModel?()
Here is a rationale: imagine you have a type with a failable initializer AND a function that takes an optional value of this type, with default nil:
protocol P { }
struct Value {
init(_ array:[P?]) { … }
init?(_ nsarray: NSArray) { … }
}
func function(value: Value? = nil) { … }
The problem is that when the failable initializer fails, the function may not behave as expected:
let array: NSArray = …
function(Value(array)) // May not do what is expected
With the proposed alternative, the Swift compiler would force the code to read:
let array: NSArray = …
function(Value?(array)) // Now this is clearly bad. We need a value.
And the user is more likely to turn it into the correct code:
let array: NSArray = …
guard let value = Value(array) else {
// process problem
}
function(value)
With the current state of Swift, how could the code above be fixed? By "fixed" I mean that it’s impossible for the user to trigger the default function value without knowing it:
1. Don’t use nil as a sentinel for the default value, and split the function in two variants:
protocol P { }
struct Value {
init(_ array:[P?]) { … }
init?(_ nsarray: NSArray) { … }
}
func function() { … }
func function(value: Value) { … }
let array: NSArray = …
function(Value(array)) // OK: does not compile
It works, BUT it may lead to an API explosion.
2. Don’t use nil as a sentinel for the default value, and use a special sentinel value instead:
protocol P { }
struct Value {
static var DefaultValue: Value = ...
init(_ array:[P?]) { }
init?(_ nsarray: NSArray) { }
}
func function(value: Value = Value.DefaultValue) { }
let array: NSArray = …
function(Value(array)) // OK: does not compile
It works, BUT not all types can easily lock a value for such a purpose. Plus it’s a very uncommon pattern.
I don’t see any other way to fix the problem.
So I would quite welcome the alternative proposed by James Campbell.
Gwendal
> Le 7 mars 2016 à 16:40, James Campbell via swift-evolution <swift-evolution at swift.org> a écrit :
>
> This is my draft proposal.
>
> https://github.com/jcampbell05/swift-evolution/blob/master/proposals/0045-remove-falliable-initilizer.md <https://github.com/jcampbell05/swift-evolution/blob/master/proposals/0045-remove-falliable-initilizer.md>
>
> Let me know your thoughts.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160307/b576a12d/attachment.html>
More information about the swift-evolution
mailing list