> 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