> On Mar 20, 2017, at 8:07 PM, Greg Parker <gpar...@apple.com> wrote:
> 
> This needs more explanation. It is allowed for a subclass to implement a 
> convenience initializer that has the same signature as a superclass 
> convenience initializer or a superclass designated initializer. The 
> convenience-over-convenience case is not technically overriding, but it is 
> misleading to say only that a convenience initializer cannot be overridden. 
> Do factory initializers follow exactly the same rules here as convenience 
> initializers?

Yes, that is what I meant. For simplicity, I think the factory initializer 
inheritance rules should match exactly that of convenience initializers.

> In addition: designated initializers and convenience initializers have rules 
> about which other initializers can be called from an implementation. These 
> rules are intended to guarantee that the chain of designated initializers is 
> called correctly. What are the precise rules for factory initializers calling 
> other initializers? What are the precise rules for non-factory initializers 
> calling factory initializers?

Factory initializers can call any other initializers. Since calling convenience 
initializers would still call required initializers, the chain would be correct 
(unless I’m missing something). As for other initializers calling factory 
initializers, my gut says this should not be allowed. Factory initializers are 
supposed to initialize and return a value, whereas other initializers 
implicitly assign to self. Therefore calling a factory initializer from a 
self-assigning initializer wouldn’t do much, and I don’t see any benefit to 
allowing this.


> On Mar 21, 2017, at 8:49 AM, David Rönnqvist <david.ronnqv...@gmail.com> 
> wrote:
> 
> Forgive me if that has already been discussed in the email threads prior to 
> the proposal, but what I’m missing from this proposal is a discussion of the 
> problems factory initializers solve (other than the examples at the end) and 
> an explanation of why factory initializers are the right solution to 
> that/those problems in Swift.

I can answer this anecdotally; when learning iOS development and Objective-C, 
it was (in my opinion) hard to know whether an Objective-C class was meant to 
be initialized via [[Class alloc] initWithParameters:] or [Class 
classWithParameters:]. Pre-ARC this did actually have meaning, but post ARC/iOS 
5 it just seemed to be whatever the framework developer preferred (not to 
mention that [Class new] was also another option…).

When Swift combined all these forms into one common Class(parameters:) format, 
this greatly reduced this cognitive load. However, as outlined in the proposal, 
this meant that the factory pattern had to be moved out of the initializers and 
back into class methods. Because of this, now if you want to implement the 
factory pattern, you’re bringing back this same confusion from Objective-C; the 
client has to remember whether your class is initialized via standard 
Class(parameters:) syntax, or by calling a class method 
Class.classWithParameters(). Ultimately, I don’t believe there should be a 
difference between the two for the average programmer. You want an instance of 
the class, so you should retrieve one by calling an initializer. They don’t 
need to know or care whether the initializer is directly assigning to self or 
returning a value, as long as they get the value they need.

Beyond this, however, I think the factory initializers on protocols is one of 
this proposal’s biggest wins. For protocol oriented programming, it’s nice to 
be apply to supply a default implementation so client’s don’t need to declare 
their own type. However, if you come across a new codebase/framework, you might 
not know the difference between the specific type you’re using and the protocol 
itself (or even which one is which). I’ve personally encountered this many 
times with Apple’s frameworks, such as UIActivityItemProvider and 
UIActivityItemSource (which one is the protocol and which one is the type? Hard 
to know and remember when first using them). With factory initializers on 
protocol extensions, the initializer can return a private type conforming to 
the protocol, so again there’s no need to worry about what is the concrete type 
and what is the protocol.

P.S. Phase 2 End Question

I didn’t realize until today that apparently Swift 4 Phase 2 ends tomorrow. Is 
this true, and does that mean this is now too late to make it into Swift 4?
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to