[Proposal] Factory Initializers

FWIW, even in Swift2, factory initializer is possible.

I've post a gist here:
https://gist.github.com/rintaro/9eadc2720ac8be6a7898
It's pretty hackish though :slight_smile:

路路路

2016-03-22 15:16 GMT+09:00 Riley Testut via swift-evolution < swift-evolution@swift.org>:

Hey all!

Very sorry, restored my MacBook at the beginning of the calendar year, and
forgot to re-subscribe to Swift-Evolution :smile:. Once I realized this, I
decided to hold off on pushing this forward till after Swift 2.2, and now
that it's been released, I'd love to make moves on this!

So, is there still an interest in the proposal? If so, I'll write up a new
proposal with everyone's feedback, and then post it here for more
discussion. I think this would very valuable (and would certainly help a
bunch in my current app), but want to see where everyone stands!

Riley Testut

On Feb 8, 2016, at 11:26 AM, Charles Srstka <cocoadev@charlessoft.com> > wrote:

>> On Dec 17, 2015, at 3:41 PM, Riley Testut via swift-evolution < > swift-evolution@swift.org> wrote:
>>
>> Recently, I proposed the idea of adding the ability to implement the
"class cluster" pattern from Cocoa (Touch) in Swift. However, as we
discussed it and came up with different approaches, it evolved into a
functionality that I believe is far more beneficial to Swift, and
subsequently should be the focus of its own proposal. So here is the
improved (pre-)proposal:
>>
>> # Factory Initializers
>>
>> The "factory" pattern is common in many languages, including
Objective-C. Essentially, instead of initializing a type directly, a method
is called that returns an instance of the appropriate type determined by
the input parameters. Functionally this works well, but ultimately it
forces the client of the API to remember to call the factory method
instead, rather than the type's initializer. This might seem like a minor
gripe, but given that we want Swift to be as approachable as possible to
new developers, I think we can do better in this regard.
>>
>> Rather than have a separate factory method, I propose we build the
factory pattern right into Swift, by way of specialized 鈥渇actory
initializers鈥. The exact syntax was proposed by Philippe Hausler from the
previous thread, and I think it is an excellent solution:
>>
>> class AbstractBase {
>> public factory init(type: InformationToSwitchOn) {
>> return ConcreteImplementation(type)
>> }
>> }
>>
>> class ConcreteImplementation : AbstractBase {
>>
>> }
>>
>> Why exactly would this be useful in practice? In my own development,
I鈥檝e come across a few places where this would especially be relevant:
>>
>> ## Class Cluster/Abstract Classes
>> This was the reasoning behind the original proposal, and I still think
it would be a very valid use case. The public superclass would declare all
the public methods, and could delegate off the specific implementations to
the private subclasses. Alternatively, this method could be used as an easy
way to handle backwards-compatibility: rather than litter the code with
branches depending on the OS version, simply return the OS-appropriate
subclass from the factory initializer. Very useful.
>>
>> ## Protocol Initializers
>> Proposed by Brent Royal-Gordon, we could use factory initializers with
protocol extensions to return the appropriate instance conforming to a
protocol for the given needs. Similar to the class cluster/abstract class
method, but can work with structs too. This would be closer to the factory
method pattern, since you don鈥檛 need to know exactly what type is returned,
just the protocol it conforms to.
>>
>> ## Initializing Storyboard-backed View Controller
>> This is more specific to Apple Frameworks, but having factory
initializers could definitely help here. Currently, view controllers
associated with a storyboard must be initialized from the client through a
factory method on the storyboard instance (storyboard.
instantiateViewControllerWithIdentifier()). This works when the entire flow
of the app is storyboard based, but when a single storyboard is used to
configure a one-off view controller, having to initialize through the
storyboard is essentially use of private implementation details; it
shouldn鈥檛 matter whether the VC was designed in code or storyboards,
ultimately a single initializer should 鈥渄o the right thing鈥 (just as it
does when using XIBs directly). A factory initializer for a View Controller
subclass could handle the loading of the storyboard and returning the
appropriate view controller.
>>
>> Here are some comments from the previous thread that I believe are
still relevant:
>>
>>
>>> On Dec 9, 2015, at 1:06 PM, Philippe Hausler <phausler@apple.com> > wrote:
>>>
>>> I can definitely attest that in implementing Foundation we could have
much more idiomatic swift and much more similar behavior to the way
Foundation on Darwin actually works if we had factory initializers.
>>
>>
>>> On Dec 7, 2015, at 5:24 PM, Brent Royal-Gordon <brent@architechies.com> > wrote:
>>>
>>> A `protocol init` in a protocol extension creates an initializer which
is *not* applied to types conforming to the protocol. Instead, it is
actually an initializer on the protocol itself. `self` is the protocol
metatype, not an instance of anything. The provided implementation should
`return` an instance conforming to (and implicitly casted to) the protocol.
Just like any other initializer, a `protocol init` can be failable or
throwing.
>>>
>>> Unlike other initializers, Swift usually won鈥檛 be able to tell at
compile time which concrete type will be returned by a protocol init(),
reducing opportunities to statically bind methods and perform other
optimization tricks. Frankly, though, that鈥檚 just the cost of doing
business. If you want to select a type dynamically, you鈥檙e going to lose
the ability to aggressively optimize calls to the resulting instance.
>>
>>
>> I鈥檇 love to hear everyone鈥檚 thoughts on this!
>>
>> Best,
>> Riley Testut
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> Was any proposal for this ever written up? It would be really useful to
have, and it appeared to have the support of several Apple staff members.
>
> Charles
>
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

1 Like

Hi again everyone!

Now that Swift 4 Stage 2 proposals are being considered, I thought it might be time to revisit this proposal and see if it might align with the goals set forth for Swift 4.

As a quick tl;dr, this proposal describes a new "factory initializer" that would allow you to return a value from an initializer. This would have several benefits, as mentioned in the proposal itself as well as throughout this mailing list. For convenience, here's a link to the proposal on GitHub: https://github.com/rileytestut/swift-evolution/blob/master/proposals/NNNN-factory-initializers.md

Would love to hear any more comments on this proposal, and if we feel this is appropriate for considering for Swift 4 I'll happily re-open the pull request!

Riley Testut

路路路

On Nov 19, 2016, at 7:45 AM, arkadi daniyelian <arkdan@icloud.com> wrote:

i would appreciate this feature.

For unexperienced developers, its often hard to recognize *when* factory is a good fit to do the job, and how exactly approach the implementation. I imagine having this feature built into the language may help to choose and implement factory when its the right thing to do.

On Nov 18, 2016, at 12:23 AM, Charles Srstka via swift-evolution <swift-evolution@swift.org> wrote:

Is there any chance of reviving this? It seems to me that since this would require Swift initializers to be implemented internally in such a way that they can return a value (as Objective-C init methods do), it may affect ABI stability and thus may be germane to the current stage of Swift 4 development.

Charles

On Dec 17, 2015, at 3:41 PM, Riley Testut via swift-evolution <swift-evolution@swift.org> wrote:

Recently, I proposed the idea of adding the ability to implement the "class cluster" pattern from Cocoa (Touch) in Swift. However, as we discussed it and came up with different approaches, it evolved into a functionality that I believe is far more beneficial to Swift, and subsequently should be the focus of its own proposal. So here is the improved (pre-)proposal:

# Factory Initializers

The "factory" pattern is common in many languages, including Objective-C. Essentially, instead of initializing a type directly, a method is called that returns an instance of the appropriate type determined by the input parameters. Functionally this works well, but ultimately it forces the client of the API to remember to call the factory method instead, rather than the type's initializer. This might seem like a minor gripe, but given that we want Swift to be as approachable as possible to new developers, I think we can do better in this regard.

Rather than have a separate factory method, I propose we build the factory pattern right into Swift, by way of specialized 鈥渇actory initializers鈥. The exact syntax was proposed by Philippe Hausler from the previous thread, and I think it is an excellent solution:

class AbstractBase {
public factory init(type: InformationToSwitchOn) {
聽聽聽聽聽return ConcreteImplementation(type)
}
}

class ConcreteImplementation : AbstractBase {

}

Why exactly would this be useful in practice? In my own development, I鈥檝e come across a few places where this would especially be relevant:

## Class Cluster/Abstract Classes
This was the reasoning behind the original proposal, and I still think it would be a very valid use case. The public superclass would declare all the public methods, and could delegate off the specific implementations to the private subclasses. Alternatively, this method could be used as an easy way to handle backwards-compatibility: rather than litter the code with branches depending on the OS version, simply return the OS-appropriate subclass from the factory initializer. Very useful.

## Protocol Initializers
Proposed by Brent Royal-Gordon, we could use factory initializers with protocol extensions to return the appropriate instance conforming to a protocol for the given needs. Similar to the class cluster/abstract class method, but can work with structs too. This would be closer to the factory method pattern, since you don鈥檛 need to know exactly what type is returned, just the protocol it conforms to.

## Initializing Storyboard-backed View Controller
This is more specific to Apple Frameworks, but having factory initializers could definitely help here. Currently, view controllers associated with a storyboard must be initialized from the client through a factory method on the storyboard instance (storyboard. instantiateViewControllerWithIdentifier()). This works when the entire flow of the app is storyboard based, but when a single storyboard is used to configure a one-off view controller, having to initialize through the storyboard is essentially use of private implementation details; it shouldn鈥檛 matter whether the VC was designed in code or storyboards, ultimately a single initializer should 鈥渄o the right thing鈥 (just as it does when using XIBs directly). A factory initializer for a View Controller subclass could handle the loading of the storyboard and returning the appropriate view controller.

Here are some comments from the previous thread that I believe are still relevant:

On Dec 9, 2015, at 1:06 PM, Philippe Hausler <phausler@apple.com> wrote:

I can definitely attest that in implementing Foundation we could have much more idiomatic swift and much more similar behavior to the way Foundation on Darwin actually works if we had factory initializers.

On Dec 7, 2015, at 5:24 PM, Brent Royal-Gordon <brent@architechies.com> wrote:

A `protocol init` in a protocol extension creates an initializer which is *not* applied to types conforming to the protocol. Instead, it is actually an initializer on the protocol itself. `self` is the protocol metatype, not an instance of anything. The provided implementation should `return` an instance conforming to (and implicitly casted to) the protocol. Just like any other initializer, a `protocol init` can be failable or throwing.

Unlike other initializers, Swift usually won鈥檛 be able to tell at compile time which concrete type will be returned by a protocol init(), reducing opportunities to statically bind methods and perform other optimization tricks. Frankly, though, that鈥檚 just the cost of doing business. If you want to select a type dynamically, you鈥檙e going to lose the ability to aggressively optimize calls to the resulting instance.

I鈥檇 love to hear everyone鈥檚 thoughts on this!

Best,
Riley Testut
_______________________________________________
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

I鈥檓 not opposed to assigning to self directly in convenience initializers (especially if there is already support for it in the ABI). My only concern would be that it feels less 鈥渘atural鈥 to do so than to simply return a value from the initializer.

My instinct agrees with that. Also, reassigning self raises the question of whether an object is allocated (and partly initialized?) before the reassignment. Even if we can answer those questions in some clear way, I鈥檇 rather not have them come up at all.

That being said, I think that鈥檚 a very negligible disadvantage (if even that), and if assigning to self is the easiest way to pull this off, I鈥檓 all for it.

However, should we keep convenience initializers as the only way to assign self directly, and required initializers keep the same behavior as they do today? And then would it make sense to disable the assignment to self in struct required initializers to keep things consistent? Don鈥檛 have a strong preference for any of these, but I do think they鈥檙e worth discussing.

Now I'm confused: I thought the idea should enable class clusters, i.e. allowing AbstractBaseClass(42) to return something with the *dynamic* type of ConcreteImplementation but still the static type of AbstractBaseClass.
Otherwise I would just call ConcreteImplementation(42) if I wanted something of that static type.

Got it. If that is the case, then yes, something like a 鈥渇actory init鈥 makes sense to me. It is unfortunate that such a thing would make the swift initializer model even MORE complex :slight_smile: but it is probably still the right way to go.

In the implementation model, if not the language model, convenience inits today pretty much already are factory initializers, since the ABI allows for a different `self` object to be returned as long as it's a subclass of the current type, much like a factory method. Instead of adding another wrinkle to the initializer model, we could embrace this, and allow convenience inits to reassign `self` as in ObjC. This would also bring more consistency between struct and class initializers, since struct initializers are already able to reassign `self` as well. We have to interop with the [[T alloc] init] model for ObjC classes, so we'd have to deallocate a wasted empty object if a convenience initializer for an @objc class changes self, but the ABI for pure Swift convenience initializers could be made to be callee-allocating to avoid that performance problem.

-Joe
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto: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

-Dave

路路路

On Dec 18, 2015, at 3:20 PM, Riley Testut via swift-evolution <swift-evolution@swift.org> wrote:

On Dec 18, 2015, at 3:06 PM, Joe Groff via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Dec 18, 2015, at 12:39 PM, Chris Lattner via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

On Dec 18, 2015, at 8:15 AM, Thorsten Seitz <tseitz42@icloud.com <mailto:tseitz42@icloud.com>> wrote:

I guess a better question here is, is it worth modifying the existing compiler/ABI behavior to explicitly allow returning instances from convenience initializers? Personally, while I prefer the use of return statements (especially because they're already used to return nil from failable initializers), I know that finalizing Swift 3 is a priority, and if we can have essentially the same functionality while also taking advantage of what already is implemented, that might make a more sense for implementation.

Of course, I'm making plenty of assumptions about the difficulty/time to implement both of these solutions. Would love to hear what the expected methodology would be to implement both of those, and if anyone has genuinely strong preferences either way.

路路路

On Dec 18, 2015, at 6:53 PM, Dave Abrahams <dabrahams@apple.com> wrote:

On Dec 18, 2015, at 3:20 PM, Riley Testut via swift-evolution <swift-evolution@swift.org> wrote:

I鈥檓 not opposed to assigning to self directly in convenience initializers (especially if there is already support for it in the ABI). My only concern would be that it feels less 鈥渘atural鈥 to do so than to simply return a value from the initializer.

My instinct agrees with that. Also, reassigning self raises the question of whether an object is allocated (and partly initialized?) before the reassignment. Even if we can answer those questions in some clear way, I鈥檇 rather not have them come up at all.

That being said, I think that鈥檚 a very negligible disadvantage (if even that), and if assigning to self is the easiest way to pull this off, I鈥檓 all for it.

However, should we keep convenience initializers as the only way to assign self directly, and required initializers keep the same behavior as they do today? And then would it make sense to disable the assignment to self in struct required initializers to keep things consistent? Don鈥檛 have a strong preference for any of these, but I do think they鈥檙e worth discussing.

On Dec 18, 2015, at 3:06 PM, Joe Groff via swift-evolution <swift-evolution@swift.org> wrote:

On Dec 18, 2015, at 12:39 PM, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

On Dec 18, 2015, at 8:15 AM, Thorsten Seitz <tseitz42@icloud.com> wrote:

Now I'm confused: I thought the idea should enable class clusters, i.e. allowing AbstractBaseClass(42) to return something with the *dynamic* type of ConcreteImplementation but still the static type of AbstractBaseClass.
Otherwise I would just call ConcreteImplementation(42) if I wanted something of that static type.

Got it. If that is the case, then yes, something like a 鈥渇actory init鈥 makes sense to me. It is unfortunate that such a thing would make the swift initializer model even MORE complex :-) but it is probably still the right way to go.

In the implementation model, if not the language model, convenience inits today pretty much already are factory initializers, since the ABI allows for a different `self` object to be returned as long as it's a subclass of the current type, much like a factory method. Instead of adding another wrinkle to the initializer model, we could embrace this, and allow convenience inits to reassign `self` as in ObjC. This would also bring more consistency between struct and class initializers, since struct initializers are already able to reassign `self` as well. We have to interop with the [[T alloc] init] model for ObjC classes, so we'd have to deallocate a wasted empty object if a convenience initializer for an @objc class changes self, but the ABI for pure Swift convenience initializers could be made to be callee-allocating to avoid that performance problem.

-Joe
_______________________________________________
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

-Dave

Glad to see there's definitely some interest in this community then! I would love to start writing up a final proposal to submit to the Swift-Evolution repo, but I think that last piece of information needed would be the actual method of initialization, specifically should we allow for returning instances from convenience initializers, or should we simply assign to self?

Personally, I think returning from the initializer makes the most sense, especially because "self" in a protocol extension seems ambiguous. However, I'm not that much in favor that I couldn't be convinced to simply assign to self, because that already has some low level support in the language. Anyone have strong thoughts one way or another?

Assigning to self was always a bit weird. I think returning an instance makes more sense intuitively. It鈥檚 also, as you say, unclear exactly what 鈥渟elf鈥 even means in the context of a protocol.

Probably the way I鈥檇 do it would be to have the method declared 鈥渇actory init鈥 and be required to return an object.

+1 assuming we want to use the same syntax in type and protocol extensions. I don't like assign-to-self in a protocol extension.

Returning the instance also matches how factory methods are usually done in other languages. That shouldn't carry too much weight but it is worth noting.

路路路

Sent from my iPad

On Dec 23, 2015, at 11:57 PM, Charles Srstka via swift-evolution <swift-evolution@swift.org> wrote:

On Dec 23, 2015, at 11:09 PM, Riley Testut <rileytestut@gmail.com> wrote:

Charles

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

+1 for factory initializers on classes.

-0.5 for factory initializers on protocols.

I believe there is a strong pairing between Dependency Inversion (from SOLID principals, that you should depend on abstractions like protocols instead of concretions like a particular class) and dependency injection (that your implementation should be given the instances of the abstraction you need rather than creating concrete classes on its own)

By having your code depend on a factory initializer at runtime to get its abstractions, you are limited in your ability to adapt the code to other scenarios such as testing. You may for instance need to put your factory initializer on your protocol into a 鈥榯esting mode鈥 in order to perform unit testing on your code.

Or in other words, while its already possible to have factory methods and factory functions, I worry that factory initializers will result in APIs being unknowingly designed toward a higher degree of coupling in their code. Having factory initializers provides a greater degree of 鈥渂lessing鈥 in API design to (what I at least consider to be) an anti-pattern.

-DW

路路路

On Mar 22, 2016, at 4:42 AM, Patrick Pijnappel via swift-evolution <swift-evolution@swift.org> wrote:

Definitely a +1 here on interest for this proposal, have run into this several times.

On Tue, Mar 22, 2016 at 5:16 PM, Riley Testut via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Hey all!

Very sorry, restored my MacBook at the beginning of the calendar year, and forgot to re-subscribe to Swift-Evolution :smile:. Once I realized this, I decided to hold off on pushing this forward till after Swift 2.2, and now that it's been released, I'd love to make moves on this!

So, is there still an interest in the proposal? If so, I'll write up a new proposal with everyone's feedback, and then post it here for more discussion. I think this would very valuable (and would certainly help a bunch in my current app), but want to see where everyone stands!

Riley Testut

On Feb 8, 2016, at 11:26 AM, Charles Srstka <cocoadev@charlessoft.com <mailto:cocoadev@charlessoft.com>> wrote:

>> On Dec 17, 2015, at 3:41 PM, Riley Testut via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>
>> Recently, I proposed the idea of adding the ability to implement the "class cluster" pattern from Cocoa (Touch) in Swift. However, as we discussed it and came up with different approaches, it evolved into a functionality that I believe is far more beneficial to Swift, and subsequently should be the focus of its own proposal. So here is the improved (pre-)proposal:
>>
>> # Factory Initializers
>>
>> The "factory" pattern is common in many languages, including Objective-C. Essentially, instead of initializing a type directly, a method is called that returns an instance of the appropriate type determined by the input parameters. Functionally this works well, but ultimately it forces the client of the API to remember to call the factory method instead, rather than the type's initializer. This might seem like a minor gripe, but given that we want Swift to be as approachable as possible to new developers, I think we can do better in this regard.
>>
>> Rather than have a separate factory method, I propose we build the factory pattern right into Swift, by way of specialized 鈥渇actory initializers鈥. The exact syntax was proposed by Philippe Hausler from the previous thread, and I think it is an excellent solution:
>>
>> class AbstractBase {
>> public factory init(type: InformationToSwitchOn) {
>> return ConcreteImplementation(type)
>> }
>> }
>>
>> class ConcreteImplementation : AbstractBase {
>>
>> }
>>
>> Why exactly would this be useful in practice? In my own development, I鈥檝e come across a few places where this would especially be relevant:
>>
>> ## Class Cluster/Abstract Classes
>> This was the reasoning behind the original proposal, and I still think it would be a very valid use case. The public superclass would declare all the public methods, and could delegate off the specific implementations to the private subclasses. Alternatively, this method could be used as an easy way to handle backwards-compatibility: rather than litter the code with branches depending on the OS version, simply return the OS-appropriate subclass from the factory initializer. Very useful.
>>
>> ## Protocol Initializers
>> Proposed by Brent Royal-Gordon, we could use factory initializers with protocol extensions to return the appropriate instance conforming to a protocol for the given needs. Similar to the class cluster/abstract class method, but can work with structs too. This would be closer to the factory method pattern, since you don鈥檛 need to know exactly what type is returned, just the protocol it conforms to.
>>
>> ## Initializing Storyboard-backed View Controller
>> This is more specific to Apple Frameworks, but having factory initializers could definitely help here. Currently, view controllers associated with a storyboard must be initialized from the client through a factory method on the storyboard instance (storyboard. instantiateViewControllerWithIdentifier()). This works when the entire flow of the app is storyboard based, but when a single storyboard is used to configure a one-off view controller, having to initialize through the storyboard is essentially use of private implementation details; it shouldn鈥檛 matter whether the VC was designed in code or storyboards, ultimately a single initializer should 鈥渄o the right thing鈥 (just as it does when using XIBs directly). A factory initializer for a View Controller subclass could handle the loading of the storyboard and returning the appropriate view controller.
>>
>> Here are some comments from the previous thread that I believe are still relevant:
>>
>>
>>> On Dec 9, 2015, at 1:06 PM, Philippe Hausler <phausler@apple.com <mailto:phausler@apple.com>> wrote:
>>>
>>> I can definitely attest that in implementing Foundation we could have much more idiomatic swift and much more similar behavior to the way Foundation on Darwin actually works if we had factory initializers.
>>
>>
>>> On Dec 7, 2015, at 5:24 PM, Brent Royal-Gordon <brent@architechies.com <mailto:brent@architechies.com>> wrote:
>>>
>>> A `protocol init` in a protocol extension creates an initializer which is *not* applied to types conforming to the protocol. Instead, it is actually an initializer on the protocol itself. `self` is the protocol metatype, not an instance of anything. The provided implementation should `return` an instance conforming to (and implicitly casted to) the protocol. Just like any other initializer, a `protocol init` can be failable or throwing.
>>>
>>> Unlike other initializers, Swift usually won鈥檛 be able to tell at compile time which concrete type will be returned by a protocol init(), reducing opportunities to statically bind methods and perform other optimization tricks. Frankly, though, that鈥檚 just the cost of doing business. If you want to select a type dynamically, you鈥檙e going to lose the ability to aggressively optimize calls to the resulting instance.
>>
>>
>> I鈥檇 love to hear everyone鈥檚 thoughts on this!
>>
>> Best,
>> Riley Testut
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> Was any proposal for this ever written up? It would be really useful to have, and it appeared to have the support of several Apple staff members.
>
> Charles
>
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto: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

-0.5 for factory initializers on protocols.

I believe there is a strong pairing between Dependency Inversion (from SOLID principals, that you should depend on abstractions like protocols instead of concretions like a particular class) and dependency injection (that your implementation should be given the instances of the abstraction you need rather than creating concrete classes on its own)

By having your code depend on a factory initializer at runtime to get its abstractions, you are limited in your ability to adapt the code to other scenarios such as testing. You may for instance need to put your factory initializer on your protocol into a 鈥榯esting mode鈥 in order to perform unit testing on your code.

Or in other words, while its already possible to have factory methods and factory functions, I worry that factory initializers will result in APIs being unknowingly designed toward a higher degree of coupling in their code. Having factory initializers provides a greater degree of 鈥渂lessing鈥 in API design to (what I at least consider to be) an anti-pattern.

Testability and dependency injection are red herrings; factory initializers are no better or worse for those than any other mechanism in the language.

For instance, suppose you have an Image protocol with a factory initializer on its data:

聽聽protocol Image {
聽聽聽聽init(data: NSData)
聽聽聽聽var data: NSData { get }
聽聽聽聽
聽聽聽聽var size: CGSize
聽聽聽聽func draw(at point: CGPoint, in context: CGContext)
聽聽}
聽聽
聽聽extension Image {
聽聽聽聽factory init(data: NSData) {
聽聽聽聽聽聽if isJPEG(data: data) {
聽聽聽聽聽聽聽聽self = JPEGImage(data: data)
聽聽聽聽聽聽}
聽聽聽聽聽聽else if isPNG(data: data) {
聽聽聽聽聽聽聽聽self = PNGImage(data: data)
聽聽聽聽聽聽}
聽聽聽聽聽聽else {
聽聽聽聽聽聽聽聽self = BitmapImage(data: data)
聽聽聽聽聽聽}
聽聽聽聽}
聽聽}

Certainly if your code says `Image(data:)` directly, this violates dependency injection:

聽聽class ImageDownloader: Downloader {
聽聽聽聽var completion: (Image?, Error?) -> Void
聽聽聽聽
聽聽聽聽func didComplete(data: NSData) {
聽聽聽聽聽聽let image = Image(data: data)
聽聽聽聽聽聽completion(image, nil)
聽聽聽聽}
聽聽}

But the same would be true if we didn't have factory inits and instead had a static method or function that did the same thing. The solution is not to ban factory methods; it's to keep using dependency injection.

聽聽class ImageDownloader: Downloader {
聽聽聽聽var completion: (Image?, Error?) -> Void

聽聽聽聽// Defaulted for convenience in normal use, but a test can change it.
聽聽聽聽var makeImage: NSData -> Image = Image.init(data:)
聽聽聽聽
聽聽聽聽func didComplete(data: NSData) {
聽聽聽聽聽聽let image = makeImage(data)
聽聽聽聽聽聽completion(image, nil)
聽聽聽聽}
聽聽}

Similarly, if you think the factory init is not testable enough, you are not complaining about it being a factory init; you are complaining about it being poorly factored. The solution is to improve its factoring:

聽聽func imageType(for data: NSData) -> Image.Type {
聽聽聽聽if isJPEG(data: data) {
聽聽聽聽聽聽return JPEGImage.self
聽聽聽聽}
聽聽聽聽else if isPNG(data: data) {
聽聽聽聽聽聽return PNGImage.self
聽聽聽聽}
聽聽聽聽else {
聽聽聽聽聽聽return BitmapImage.self
聽聽聽聽}
聽聽}
聽聽
聽聽extension Image {
聽聽聽聽// Defaulted for convenience in normal use
聽聽聽聽factory init(data: NSData, decideImageType: NSData -> Image.Type = imageType(for:)) {
聽聽聽聽聽聽let type = decideImageType(data)
聽聽聽聽聽聽self = type.init(data: data)
聽聽聽聽}
聽聽}

With this in place, you can separately test that:

* `imageType(for:)` correctly detects image types.
* `Image.init` constructs an image of the type returned by `decideImageType`.

Which lets you test this design without forcing you to construct any unwanted concrete types.

So in short, I think factory inits are no less testable than any other code, and if you're running into trouble because you're not injecting dependencies, the solution is, quite simply, to inject dependencies.

路路路

--
Brent Royal-Gordon
Architechies

Big +1.

Two small nits/questions:

- What's the motivation behind using `return` rather than self-
聽聽assignment, like we currently have in inits for structs/enums and
聽聽protocol extensions? I didn't follow the original discussion in depth,
聽聽so excuse me if this has been hashed out before.
- Is the "factory" keyword truly necessary, or could it be implied by
聽聽"required" and using self-assignment in the init body?

Best,

聽聽Zachary Waldowski

聽聽zach@waldowski.me

路路路

On Fri, Mar 17, 2017, at 12:26 PM, Riley Testut via swift-evolution wrote:

Hi again everyone!

Now that Swift 4 Stage 2 proposals are being considered, I thought it
might be time to revisit this proposal and see if it might align with
the goals set forth for Swift 4.

As a quick tl;dr, this proposal describes a new "factory initializer"
that would allow you to return a value from an initializer. This would
have several benefits, as mentioned in the proposal itself as well as
throughout this mailing list. For convenience, here's a link to the
proposal on GitHub:
https://github.com/rileytestut/swift-evolution/blob/master/proposals/NNNN-factory-initializers.md

Would love to hear any more comments on this proposal, and if we feel
this is appropriate for considering for Swift 4 I'll happily re-open
the pull request!

Riley Testut

On Nov 19, 2016, at 7:45 AM, arkadi daniyelian > <arkdan@icloud.com> wrote:

i would appreciate this feature.

For unexperienced developers, its often hard to recognize *when*
factory is a good fit to do the job, and how exactly approach the
implementation. I imagine having this feature built into the
language may help to choose and implement factory when its the right
thing to do.

On Nov 18, 2016, at 12:23 AM, Charles Srstka via swift-evolution <swift- >>> evolution@swift.org> wrote:

Is there any chance of reviving this? It seems to me that since this
would require Swift initializers to be implemented internally in
such a way that they can return a value (as Objective-C init methods
do), it may affect ABI stability and thus may be germane to the
current stage of Swift 4 development.

Charles

On Dec 17, 2015, at 3:41 PM, Riley Testut via swift-evolution <swift- >>>> evolution@swift.org> wrote:

Recently, I proposed the idea of adding the ability to implement
the "class cluster" pattern from Cocoa (Touch) in Swift. However,
as we discussed it and came up with different approaches, it
evolved into a functionality that I believe is far more beneficial
to Swift, and subsequently should be the focus of its own proposal.
So here is the improved (pre-)proposal:

# Factory Initializers

The "factory" pattern is common in many languages, including Objective-
C. Essentially, instead of initializing a type directly, a method
is called that returns an instance of the appropriate type
determined by the input parameters. Functionally this works well,
but ultimately it forces the client of the API to remember to call
the factory method instead, rather than the type's initializer.
This might seem like a minor gripe, but given that we want Swift to
be as approachable as possible to new developers, I think we can do
better in this regard.

Rather than have a separate factory method, I propose we build the
factory pattern right into Swift, by way of specialized 鈥渇actory
initializers鈥. The exact syntax was proposed by Philippe Hausler
from the previous thread, and I think it is an excellent solution:

class AbstractBase { public factory init(type:
InformationToSwitchOn) { return
ConcreteImplementation(type) } }

class ConcreteImplementation : AbstractBase {

}

Why exactly would this be useful in practice? In my own
development, I鈥檝e come across a few places where this would
especially be relevant:

## Class Cluster/Abstract Classes
This was the reasoning behind the original proposal, and I still
think it would be a very valid use case. The public superclass
would declare all the public methods, and could delegate off the
specific implementations to the private subclasses. Alternatively,
this method could be used as an easy way to handle backwards-
compatibility: rather than litter the code with branches depending
on the OS version, simply return the OS-appropriate subclass from
the factory initializer. Very useful.

## Protocol Initializers
Proposed by Brent Royal-Gordon, we could use factory initializers
with protocol extensions to return the appropriate instance
conforming to a protocol for the given needs. Similar to the class
cluster/abstract class method, but can work with structs too. This
would be closer to the factory method pattern, since you don鈥檛 need
to know exactly what type is returned, just the protocol it
conforms to.

## Initializing Storyboard-backed View Controller
This is more specific to Apple Frameworks, but having factory
initializers could definitely help here. Currently, view
controllers associated with a storyboard must be initialized from
the client through a factory method on the storyboard instance
(storyboard. instantiateViewControllerWithIdentifier()). This works
when the entire flow of the app is storyboard based, but when a
single storyboard is used to configure a one-off view controller,
having to initialize through the storyboard is essentially use of
private implementation details; it shouldn鈥檛 matter whether the VC
was designed in code or storyboards, ultimately a single
initializer should 鈥渄o the right thing鈥 (just as it does when using
XIBs directly). A factory initializer for a View Controller
subclass could handle the loading of the storyboard and returning
the appropriate view controller.

Here are some comments from the previous thread that I believe are
still relevant:

On Dec 9, 2015, at 1:06 PM, Philippe Hausler <phausler@apple.com> >>>>> wrote:

I can definitely attest that in implementing Foundation we could
have much more idiomatic swift and much more similar behavior to
the way Foundation on Darwin actually works if we had factory
initializers.

On Dec 7, 2015, at 5:24 PM, Brent Royal-Gordon >>>>> <brent@architechies.com> wrote:

A `protocol init` in a protocol extension creates an initializer
which is *not* applied to types conforming to the protocol.
Instead, it is actually an initializer on the protocol itself.
`self` is the protocol metatype, not an instance of anything. The
provided implementation should `return` an instance conforming to
(and implicitly casted to) the protocol. Just like any other
initializer, a `protocol init` can be failable or throwing.

Unlike other initializers, Swift usually won鈥檛 be able to tell at
compile time which concrete type will be returned by a protocol
init(), reducing opportunities to statically bind methods and
perform other optimization tricks. Frankly, though, that鈥檚 just
the cost of doing business. If you want to select a type
dynamically, you鈥檙e going to lose the ability to aggressively
optimize calls to the resulting instance.

I鈥檇 love to hear everyone鈥檚 thoughts on this!

Best, Riley Testut
_______________________________________________
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

_________________________________________________

swift-evolution mailing list

swift-evolution@swift.org

https://lists.swift.org/mailman/listinfo/swift-evolution

I am really glad to see this up again. It is definitely something that I am quite certain that all of the Foundation team and contriubters are quite enthusiastic about.

I know it would likely mean some extra work for the compiler team but factory initializers would be quite impactful not only for correctness for implementing swift-corelibs-foundation, performance for a number of cases as well as safety (I am certain we could remove some gnarly hacks in both the Foundation overlay and swift-corelibs-foundation if we could utilize factory pattern initializers)

路路路

On Mar 17, 2017, at 4:26 PM, Riley Testut via swift-evolution <swift-evolution@swift.org> wrote:

Hi again everyone!

Now that Swift 4 Stage 2 proposals are being considered, I thought it might be time to revisit this proposal and see if it might align with the goals set forth for Swift 4.

As a quick tl;dr, this proposal describes a new "factory initializer" that would allow you to return a value from an initializer. This would have several benefits, as mentioned in the proposal itself as well as throughout this mailing list. For convenience, here's a link to the proposal on GitHub: https://github.com/rileytestut/swift-evolution/blob/master/proposals/NNNN-factory-initializers.md

Would love to hear any more comments on this proposal, and if we feel this is appropriate for considering for Swift 4 I'll happily re-open the pull request!

Riley Testut

On Nov 19, 2016, at 7:45 AM, arkadi daniyelian <arkdan@icloud.com <mailto:arkdan@icloud.com>> wrote:

i would appreciate this feature.

For unexperienced developers, its often hard to recognize *when* factory is a good fit to do the job, and how exactly approach the implementation. I imagine having this feature built into the language may help to choose and implement factory when its the right thing to do.

On Nov 18, 2016, at 12:23 AM, Charles Srstka via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Is there any chance of reviving this? It seems to me that since this would require Swift initializers to be implemented internally in such a way that they can return a value (as Objective-C init methods do), it may affect ABI stability and thus may be germane to the current stage of Swift 4 development.

Charles

On Dec 17, 2015, at 3:41 PM, Riley Testut via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Recently, I proposed the idea of adding the ability to implement the "class cluster" pattern from Cocoa (Touch) in Swift. However, as we discussed it and came up with different approaches, it evolved into a functionality that I believe is far more beneficial to Swift, and subsequently should be the focus of its own proposal. So here is the improved (pre-)proposal:

# Factory Initializers

The "factory" pattern is common in many languages, including Objective-C. Essentially, instead of initializing a type directly, a method is called that returns an instance of the appropriate type determined by the input parameters. Functionally this works well, but ultimately it forces the client of the API to remember to call the factory method instead, rather than the type's initializer. This might seem like a minor gripe, but given that we want Swift to be as approachable as possible to new developers, I think we can do better in this regard.

Rather than have a separate factory method, I propose we build the factory pattern right into Swift, by way of specialized 鈥渇actory initializers鈥. The exact syntax was proposed by Philippe Hausler from the previous thread, and I think it is an excellent solution:

class AbstractBase {
public factory init(type: InformationToSwitchOn) {
聽聽聽聽聽return ConcreteImplementation(type)
}
}

class ConcreteImplementation : AbstractBase {

}

Why exactly would this be useful in practice? In my own development, I鈥檝e come across a few places where this would especially be relevant:

## Class Cluster/Abstract Classes
This was the reasoning behind the original proposal, and I still think it would be a very valid use case. The public superclass would declare all the public methods, and could delegate off the specific implementations to the private subclasses. Alternatively, this method could be used as an easy way to handle backwards-compatibility: rather than litter the code with branches depending on the OS version, simply return the OS-appropriate subclass from the factory initializer. Very useful.

## Protocol Initializers
Proposed by Brent Royal-Gordon, we could use factory initializers with protocol extensions to return the appropriate instance conforming to a protocol for the given needs. Similar to the class cluster/abstract class method, but can work with structs too. This would be closer to the factory method pattern, since you don鈥檛 need to know exactly what type is returned, just the protocol it conforms to.

## Initializing Storyboard-backed View Controller
This is more specific to Apple Frameworks, but having factory initializers could definitely help here. Currently, view controllers associated with a storyboard must be initialized from the client through a factory method on the storyboard instance (storyboard. instantiateViewControllerWithIdentifier()). This works when the entire flow of the app is storyboard based, but when a single storyboard is used to configure a one-off view controller, having to initialize through the storyboard is essentially use of private implementation details; it shouldn鈥檛 matter whether the VC was designed in code or storyboards, ultimately a single initializer should 鈥渄o the right thing鈥 (just as it does when using XIBs directly). A factory initializer for a View Controller subclass could handle the loading of the storyboard and returning the appropriate view controller.

Here are some comments from the previous thread that I believe are still relevant:

On Dec 9, 2015, at 1:06 PM, Philippe Hausler <phausler@apple.com <mailto:phausler@apple.com>> wrote:

I can definitely attest that in implementing Foundation we could have much more idiomatic swift and much more similar behavior to the way Foundation on Darwin actually works if we had factory initializers.

On Dec 7, 2015, at 5:24 PM, Brent Royal-Gordon <brent@architechies.com <mailto:brent@architechies.com>> wrote:

A `protocol init` in a protocol extension creates an initializer which is *not* applied to types conforming to the protocol. Instead, it is actually an initializer on the protocol itself. `self` is the protocol metatype, not an instance of anything. The provided implementation should `return` an instance conforming to (and implicitly casted to) the protocol. Just like any other initializer, a `protocol init` can be failable or throwing.

Unlike other initializers, Swift usually won鈥檛 be able to tell at compile time which concrete type will be returned by a protocol init(), reducing opportunities to statically bind methods and perform other optimization tricks. Frankly, though, that鈥檚 just the cost of doing business. If you want to select a type dynamically, you鈥檙e going to lose the ability to aggressively optimize calls to the resulting instance.

I鈥檇 love to hear everyone鈥檚 thoughts on this!

Best,
Riley Testut
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto: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

Huge +1

路路路

On Mar 17, 2017, at 9:26 AM, Riley Testut via swift-evolution <swift-evolution@swift.org> wrote:

Hi again everyone!

Now that Swift 4 Stage 2 proposals are being considered, I thought it might be time to revisit this proposal and see if it might align with the goals set forth for Swift 4.

As a quick tl;dr, this proposal describes a new "factory initializer" that would allow you to return a value from an initializer. This would have several benefits, as mentioned in the proposal itself as well as throughout this mailing list. For convenience, here's a link to the proposal on GitHub: https://github.com/rileytestut/swift-evolution/blob/master/proposals/NNNN-factory-initializers.md

Would love to hear any more comments on this proposal, and if we feel this is appropriate for considering for Swift 4 I'll happily re-open the pull request!

Riley Testut

On Nov 19, 2016, at 7:45 AM, arkadi daniyelian <arkdan@icloud.com <mailto:arkdan@icloud.com>> wrote:

i would appreciate this feature.

For unexperienced developers, its often hard to recognize *when* factory is a good fit to do the job, and how exactly approach the implementation. I imagine having this feature built into the language may help to choose and implement factory when its the right thing to do.

On Nov 18, 2016, at 12:23 AM, Charles Srstka via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Is there any chance of reviving this? It seems to me that since this would require Swift initializers to be implemented internally in such a way that they can return a value (as Objective-C init methods do), it may affect ABI stability and thus may be germane to the current stage of Swift 4 development.

Charles

On Dec 17, 2015, at 3:41 PM, Riley Testut via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Recently, I proposed the idea of adding the ability to implement the "class cluster" pattern from Cocoa (Touch) in Swift. However, as we discussed it and came up with different approaches, it evolved into a functionality that I believe is far more beneficial to Swift, and subsequently should be the focus of its own proposal. So here is the improved (pre-)proposal:

# Factory Initializers

The "factory" pattern is common in many languages, including Objective-C. Essentially, instead of initializing a type directly, a method is called that returns an instance of the appropriate type determined by the input parameters. Functionally this works well, but ultimately it forces the client of the API to remember to call the factory method instead, rather than the type's initializer. This might seem like a minor gripe, but given that we want Swift to be as approachable as possible to new developers, I think we can do better in this regard.

Rather than have a separate factory method, I propose we build the factory pattern right into Swift, by way of specialized 鈥渇actory initializers鈥. The exact syntax was proposed by Philippe Hausler from the previous thread, and I think it is an excellent solution:

class AbstractBase {
public factory init(type: InformationToSwitchOn) {
聽聽聽聽聽return ConcreteImplementation(type)
}
}

class ConcreteImplementation : AbstractBase {

}

Why exactly would this be useful in practice? In my own development, I鈥檝e come across a few places where this would especially be relevant:

## Class Cluster/Abstract Classes
This was the reasoning behind the original proposal, and I still think it would be a very valid use case. The public superclass would declare all the public methods, and could delegate off the specific implementations to the private subclasses. Alternatively, this method could be used as an easy way to handle backwards-compatibility: rather than litter the code with branches depending on the OS version, simply return the OS-appropriate subclass from the factory initializer. Very useful.

## Protocol Initializers
Proposed by Brent Royal-Gordon, we could use factory initializers with protocol extensions to return the appropriate instance conforming to a protocol for the given needs. Similar to the class cluster/abstract class method, but can work with structs too. This would be closer to the factory method pattern, since you don鈥檛 need to know exactly what type is returned, just the protocol it conforms to.

## Initializing Storyboard-backed View Controller
This is more specific to Apple Frameworks, but having factory initializers could definitely help here. Currently, view controllers associated with a storyboard must be initialized from the client through a factory method on the storyboard instance (storyboard. instantiateViewControllerWithIdentifier()). This works when the entire flow of the app is storyboard based, but when a single storyboard is used to configure a one-off view controller, having to initialize through the storyboard is essentially use of private implementation details; it shouldn鈥檛 matter whether the VC was designed in code or storyboards, ultimately a single initializer should 鈥渄o the right thing鈥 (just as it does when using XIBs directly). A factory initializer for a View Controller subclass could handle the loading of the storyboard and returning the appropriate view controller.

Here are some comments from the previous thread that I believe are still relevant:

On Dec 9, 2015, at 1:06 PM, Philippe Hausler <phausler@apple.com <mailto:phausler@apple.com>> wrote:

I can definitely attest that in implementing Foundation we could have much more idiomatic swift and much more similar behavior to the way Foundation on Darwin actually works if we had factory initializers.

On Dec 7, 2015, at 5:24 PM, Brent Royal-Gordon <brent@architechies.com <mailto:brent@architechies.com>> wrote:

A `protocol init` in a protocol extension creates an initializer which is *not* applied to types conforming to the protocol. Instead, it is actually an initializer on the protocol itself. `self` is the protocol metatype, not an instance of anything. The provided implementation should `return` an instance conforming to (and implicitly casted to) the protocol. Just like any other initializer, a `protocol init` can be failable or throwing.

Unlike other initializers, Swift usually won鈥檛 be able to tell at compile time which concrete type will be returned by a protocol init(), reducing opportunities to statically bind methods and perform other optimization tricks. Frankly, though, that鈥檚 just the cost of doing business. If you want to select a type dynamically, you鈥檙e going to lose the ability to aggressively optimize calls to the resulting instance.

I鈥檇 love to hear everyone鈥檚 thoughts on this!

Best,
Riley Testut
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto: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

"As for overriding, just like convenience initializers, factory initializers should not be able to be overridden by subclasses."

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?

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?

路路路

On Mar 17, 2017, at 9:26 AM, Riley Testut via swift-evolution <swift-evolution@swift.org> wrote:

Hi again everyone!

Now that Swift 4 Stage 2 proposals are being considered, I thought it might be time to revisit this proposal and see if it might align with the goals set forth for Swift 4.

As a quick tl;dr, this proposal describes a new "factory initializer" that would allow you to return a value from an initializer. This would have several benefits, as mentioned in the proposal itself as well as throughout this mailing list. For convenience, here's a link to the proposal on GitHub: https://github.com/rileytestut/swift-evolution/blob/master/proposals/NNNN-factory-initializers.md

Would love to hear any more comments on this proposal, and if we feel this is appropriate for considering for Swift 4 I'll happily re-open the pull request!

--
Greg Parker gparker@apple.com Runtime Wrangler

Needless to say: +1,000,000.

Charles

路路路

On Mar 17, 2017, at 11:26 AM, Riley Testut <rileytestut@gmail.com> wrote:

Hi again everyone!

Now that Swift 4 Stage 2 proposals are being considered, I thought it might be time to revisit this proposal and see if it might align with the goals set forth for Swift 4.

As a quick tl;dr, this proposal describes a new "factory initializer" that would allow you to return a value from an initializer. This would have several benefits, as mentioned in the proposal itself as well as throughout this mailing list. For convenience, here's a link to the proposal on GitHub: https://github.com/rileytestut/swift-evolution/blob/master/proposals/NNNN-factory-initializers.md

Would love to hear any more comments on this proposal, and if we feel this is appropriate for considering for Swift 4 I'll happily re-open the pull request!

Riley Testut

On Nov 19, 2016, at 7:45 AM, arkadi daniyelian <arkdan@icloud.com <mailto:arkdan@icloud.com>> wrote:

i would appreciate this feature.

For unexperienced developers, its often hard to recognize *when* factory is a good fit to do the job, and how exactly approach the implementation. I imagine having this feature built into the language may help to choose and implement factory when its the right thing to do.

On Nov 18, 2016, at 12:23 AM, Charles Srstka via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Is there any chance of reviving this? It seems to me that since this would require Swift initializers to be implemented internally in such a way that they can return a value (as Objective-C init methods do), it may affect ABI stability and thus may be germane to the current stage of Swift 4 development.

Charles

On Dec 17, 2015, at 3:41 PM, Riley Testut via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Recently, I proposed the idea of adding the ability to implement the "class cluster" pattern from Cocoa (Touch) in Swift. However, as we discussed it and came up with different approaches, it evolved into a functionality that I believe is far more beneficial to Swift, and subsequently should be the focus of its own proposal. So here is the improved (pre-)proposal:

# Factory Initializers

The "factory" pattern is common in many languages, including Objective-C. Essentially, instead of initializing a type directly, a method is called that returns an instance of the appropriate type determined by the input parameters. Functionally this works well, but ultimately it forces the client of the API to remember to call the factory method instead, rather than the type's initializer. This might seem like a minor gripe, but given that we want Swift to be as approachable as possible to new developers, I think we can do better in this regard.

Rather than have a separate factory method, I propose we build the factory pattern right into Swift, by way of specialized 鈥渇actory initializers鈥. The exact syntax was proposed by Philippe Hausler from the previous thread, and I think it is an excellent solution:

class AbstractBase {
public factory init(type: InformationToSwitchOn) {
聽聽聽聽聽return ConcreteImplementation(type)
}
}

class ConcreteImplementation : AbstractBase {

}

Why exactly would this be useful in practice? In my own development, I鈥檝e come across a few places where this would especially be relevant:

## Class Cluster/Abstract Classes
This was the reasoning behind the original proposal, and I still think it would be a very valid use case. The public superclass would declare all the public methods, and could delegate off the specific implementations to the private subclasses. Alternatively, this method could be used as an easy way to handle backwards-compatibility: rather than litter the code with branches depending on the OS version, simply return the OS-appropriate subclass from the factory initializer. Very useful.

## Protocol Initializers
Proposed by Brent Royal-Gordon, we could use factory initializers with protocol extensions to return the appropriate instance conforming to a protocol for the given needs. Similar to the class cluster/abstract class method, but can work with structs too. This would be closer to the factory method pattern, since you don鈥檛 need to know exactly what type is returned, just the protocol it conforms to.

## Initializing Storyboard-backed View Controller
This is more specific to Apple Frameworks, but having factory initializers could definitely help here. Currently, view controllers associated with a storyboard must be initialized from the client through a factory method on the storyboard instance (storyboard. instantiateViewControllerWithIdentifier()). This works when the entire flow of the app is storyboard based, but when a single storyboard is used to configure a one-off view controller, having to initialize through the storyboard is essentially use of private implementation details; it shouldn鈥檛 matter whether the VC was designed in code or storyboards, ultimately a single initializer should 鈥渄o the right thing鈥 (just as it does when using XIBs directly). A factory initializer for a View Controller subclass could handle the loading of the storyboard and returning the appropriate view controller.

Here are some comments from the previous thread that I believe are still relevant:

On Dec 9, 2015, at 1:06 PM, Philippe Hausler <phausler@apple.com <mailto:phausler@apple.com>> wrote:

I can definitely attest that in implementing Foundation we could have much more idiomatic swift and much more similar behavior to the way Foundation on Darwin actually works if we had factory initializers.

On Dec 7, 2015, at 5:24 PM, Brent Royal-Gordon <brent@architechies.com <mailto:brent@architechies.com>> wrote:

A `protocol init` in a protocol extension creates an initializer which is *not* applied to types conforming to the protocol. Instead, it is actually an initializer on the protocol itself. `self` is the protocol metatype, not an instance of anything. The provided implementation should `return` an instance conforming to (and implicitly casted to) the protocol. Just like any other initializer, a `protocol init` can be failable or throwing.

Unlike other initializers, Swift usually won鈥檛 be able to tell at compile time which concrete type will be returned by a protocol init(), reducing opportunities to statically bind methods and perform other optimization tricks. Frankly, though, that鈥檚 just the cost of doing business. If you want to select a type dynamically, you鈥檙e going to lose the ability to aggressively optimize calls to the resulting instance.

I鈥檇 love to hear everyone鈥檚 thoughts on this!

Best,
Riley Testut
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

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

Forgive me if that has already been discussed in the email threads prior to the proposal, but what I鈥檓 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 acknowledge that it鈥檚 a common pattern in many languages, but don鈥檛 find it a very strong argument as to why it should be built into the language.

Regards,
David

路路路

On 17 Mar 2017, at 17:26, Riley Testut via swift-evolution <swift-evolution@swift.org> wrote:

Hi again everyone!

Now that Swift 4 Stage 2 proposals are being considered, I thought it might be time to revisit this proposal and see if it might align with the goals set forth for Swift 4.

As a quick tl;dr, this proposal describes a new "factory initializer" that would allow you to return a value from an initializer. This would have several benefits, as mentioned in the proposal itself as well as throughout this mailing list. For convenience, here's a link to the proposal on GitHub: https://github.com/rileytestut/swift-evolution/blob/master/proposals/NNNN-factory-initializers.md

Would love to hear any more comments on this proposal, and if we feel this is appropriate for considering for Swift 4 I'll happily re-open the pull request!

Riley Testut

On Nov 19, 2016, at 7:45 AM, arkadi daniyelian <arkdan@icloud.com <mailto:arkdan@icloud.com>> wrote:

i would appreciate this feature.

For unexperienced developers, its often hard to recognize *when* factory is a good fit to do the job, and how exactly approach the implementation. I imagine having this feature built into the language may help to choose and implement factory when its the right thing to do.

On Nov 18, 2016, at 12:23 AM, Charles Srstka via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Is there any chance of reviving this? It seems to me that since this would require Swift initializers to be implemented internally in such a way that they can return a value (as Objective-C init methods do), it may affect ABI stability and thus may be germane to the current stage of Swift 4 development.

Charles

On Dec 17, 2015, at 3:41 PM, Riley Testut via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Recently, I proposed the idea of adding the ability to implement the "class cluster" pattern from Cocoa (Touch) in Swift. However, as we discussed it and came up with different approaches, it evolved into a functionality that I believe is far more beneficial to Swift, and subsequently should be the focus of its own proposal. So here is the improved (pre-)proposal:

# Factory Initializers

The "factory" pattern is common in many languages, including Objective-C. Essentially, instead of initializing a type directly, a method is called that returns an instance of the appropriate type determined by the input parameters. Functionally this works well, but ultimately it forces the client of the API to remember to call the factory method instead, rather than the type's initializer. This might seem like a minor gripe, but given that we want Swift to be as approachable as possible to new developers, I think we can do better in this regard.

Rather than have a separate factory method, I propose we build the factory pattern right into Swift, by way of specialized 鈥渇actory initializers鈥. The exact syntax was proposed by Philippe Hausler from the previous thread, and I think it is an excellent solution:

class AbstractBase {
public factory init(type: InformationToSwitchOn) {
聽聽聽聽聽return ConcreteImplementation(type)
}
}

class ConcreteImplementation : AbstractBase {

}

Why exactly would this be useful in practice? In my own development, I鈥檝e come across a few places where this would especially be relevant:

## Class Cluster/Abstract Classes
This was the reasoning behind the original proposal, and I still think it would be a very valid use case. The public superclass would declare all the public methods, and could delegate off the specific implementations to the private subclasses. Alternatively, this method could be used as an easy way to handle backwards-compatibility: rather than litter the code with branches depending on the OS version, simply return the OS-appropriate subclass from the factory initializer. Very useful.

## Protocol Initializers
Proposed by Brent Royal-Gordon, we could use factory initializers with protocol extensions to return the appropriate instance conforming to a protocol for the given needs. Similar to the class cluster/abstract class method, but can work with structs too. This would be closer to the factory method pattern, since you don鈥檛 need to know exactly what type is returned, just the protocol it conforms to.

## Initializing Storyboard-backed View Controller
This is more specific to Apple Frameworks, but having factory initializers could definitely help here. Currently, view controllers associated with a storyboard must be initialized from the client through a factory method on the storyboard instance (storyboard. instantiateViewControllerWithIdentifier()). This works when the entire flow of the app is storyboard based, but when a single storyboard is used to configure a one-off view controller, having to initialize through the storyboard is essentially use of private implementation details; it shouldn鈥檛 matter whether the VC was designed in code or storyboards, ultimately a single initializer should 鈥渄o the right thing鈥 (just as it does when using XIBs directly). A factory initializer for a View Controller subclass could handle the loading of the storyboard and returning the appropriate view controller.

Here are some comments from the previous thread that I believe are still relevant:

On Dec 9, 2015, at 1:06 PM, Philippe Hausler <phausler@apple.com <mailto:phausler@apple.com>> wrote:

I can definitely attest that in implementing Foundation we could have much more idiomatic swift and much more similar behavior to the way Foundation on Darwin actually works if we had factory initializers.

On Dec 7, 2015, at 5:24 PM, Brent Royal-Gordon <brent@architechies.com <mailto:brent@architechies.com>> wrote:

A `protocol init` in a protocol extension creates an initializer which is *not* applied to types conforming to the protocol. Instead, it is actually an initializer on the protocol itself. `self` is the protocol metatype, not an instance of anything. The provided implementation should `return` an instance conforming to (and implicitly casted to) the protocol. Just like any other initializer, a `protocol init` can be failable or throwing.

Unlike other initializers, Swift usually won鈥檛 be able to tell at compile time which concrete type will be returned by a protocol init(), reducing opportunities to statically bind methods and perform other optimization tricks. Frankly, though, that鈥檚 just the cost of doing business. If you want to select a type dynamically, you鈥檙e going to lose the ability to aggressively optimize calls to the resulting instance.

I鈥檇 love to hear everyone鈥檚 thoughts on this!

Best,
Riley Testut
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto: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

First, you should fix the indent in the code samples. Second, remove any access modifier from inside a protocol. Third, we don鈥檛 support default implementations directly inside protocols yet, so that鈥檚 a not valid example.

Now my personal concerns. As far as I can tell XIB files in an iOS Project are meant for UIViewControllers in first place, but it鈥檚 a common case that they are also used to create reusable UIViews. The downside of that abusage is view hierarchy clustering. Most developer creating a view of Self in Self, which smells to me like really bad code.

MyCustomView // This view is useless
聽聽聽+ MyCustomView
聽聽聽聽聽聽聽+ CustomSubview1
聽聽聽+ CustomSubview1 // This is probably a dead IBOutlet
In fact Xcode does not use the initializer from NSCoding to show a live rendered view inside interface builder, instead it will call a UIViews designated initializer init(frame:). That results that a lot of the developer write similar code like in the following snippet:

// This pattern results in a similar view cluster like mentioned above

class MyCustomView : UIView {
聽聽聽聽override init(frame: CGRect) {
聽聽聽聽聽聽聽聽let view = loadSomehowFromNib()
聽聽聽聽聽聽聽聽self.addSubview(view)
聽聽聽聽}
}
To solve this problem we鈥檇 need some functionality of factory initializers. I believe as proposed the factory initializer won鈥檛 solve that problem, because everything would be still restricted to a special initializer annotated with factory.

Personally I would want to write something like this instead.

class MyCustomView : UIView {
聽聽聽聽聽
聽聽聽聽override init(frame: CGRect) {
聽聽聽聽聽聽聽聽聽
聽聽聽聽聽聽聽聽// Instantiating from a Nib file will call `init(coder:鈥)` on MyCustomView
聽聽聽聽聽聽聽聽self = loadSomehowFromNib() // assuming () -> MyCustomView
聽聽聽聽聽聽聽聽聽
聽聽聽聽聽聽聽聽//
聽聽聽聽聽聽聽聽self.frame = frame
聽聽聽聽}
}
This should resolve the clustering issue by assigning the returned instance from the function to self and create a correct view hierarchy.

+ MyCustomView
聽聽聽聽聽聽聽+ CustomSubview1

路路路

--
Adrian Zubarev
Sent with Airmail

Am 17. M盲rz 2017 um 17:26:29, Riley Testut via swift-evolution (swift-evolution@swift.org) schrieb:

Hi again everyone!

Now that Swift 4 Stage 2 proposals are being considered, I thought it might be time to revisit this proposal and see if it might align with the goals set forth for Swift 4.

As a quick tl;dr, this proposal describes a new "factory initializer" that would allow you to return a value from an initializer. This would have several benefits, as mentioned in the proposal itself as well as throughout this mailing list. For convenience, here's a link to the proposal on GitHub: https://github.com/rileytestut/swift-evolution/blob/master/proposals/NNNN-factory-initializers.md

Would love to hear any more comments on this proposal, and if we feel this is appropriate for considering for Swift 4 I'll happily re-open the pull request!

Riley Testut

On Nov 19, 2016, at 7:45 AM, arkadi daniyelian <arkdan@icloud.com> wrote:

i would appreciate this feature.

For unexperienced developers, its often hard to recognize *when* factory is a good fit to do the job, and how exactly approach the implementation. I imagine having this feature built into the language may help to choose and implement factory when its the right thing to do.

On Nov 18, 2016, at 12:23 AM, Charles Srstka via swift-evolution <swift-evolution@swift.org> wrote:

Is there any chance of reviving this? It seems to me that since this would require Swift initializers to be implemented internally in such a way that they can return a value (as Objective-C init methods do), it may affect ABI stability and thus may be germane to the current stage of Swift 4 development.

Charles

On Dec 17, 2015, at 3:41 PM, Riley Testut via swift-evolution <swift-evolution@swift.org> wrote:

Recently, I proposed the idea of adding the ability to implement the "class cluster" pattern from Cocoa (Touch) in Swift. However, as we discussed it and came up with different approaches, it evolved into a functionality that I believe is far more beneficial to Swift, and subsequently should be the focus of its own proposal. So here is the improved (pre-)proposal:

# Factory Initializers

The "factory" pattern is common in many languages, including Objective-C. Essentially, instead of initializing a type directly, a method is called that returns an instance of the appropriate type determined by the input parameters. Functionally this works well, but ultimately it forces the client of the API to remember to call the factory method instead, rather than the type's initializer. This might seem like a minor gripe, but given that we want Swift to be as approachable as possible to new developers, I think we can do better in this regard.

Rather than have a separate factory method, I propose we build the factory pattern right into Swift, by way of specialized 鈥渇actory initializers鈥. The exact syntax was proposed by Philippe Hausler from the previous thread, and I think it is an excellent solution:

class AbstractBase {
public factory init(type: InformationToSwitchOn) {
return ConcreteImplementation(type)
}
}

class ConcreteImplementation : AbstractBase {

}

Why exactly would this be useful in practice? In my own development, I鈥檝e come across a few places where this would especially be relevant:

## Class Cluster/Abstract Classes
This was the reasoning behind the original proposal, and I still think it would be a very valid use case. The public superclass would declare all the public methods, and could delegate off the specific implementations to the private subclasses. Alternatively, this method could be used as an easy way to handle backwards-compatibility: rather than litter the code with branches depending on the OS version, simply return the OS-appropriate subclass from the factory initializer. Very useful.

## Protocol Initializers
Proposed by Brent Royal-Gordon, we could use factory initializers with protocol extensions to return the appropriate instance conforming to a protocol for the given needs. Similar to the class cluster/abstract class method, but can work with structs too. This would be closer to the factory method pattern, since you don鈥檛 need to know exactly what type is returned, just the protocol it conforms to.

## Initializing Storyboard-backed View Controller
This is more specific to Apple Frameworks, but having factory initializers could definitely help here. Currently, view controllers associated with a storyboard must be initialized from the client through a factory method on the storyboard instance (storyboard. instantiateViewControllerWithIdentifier()). This works when the entire flow of the app is storyboard based, but when a single storyboard is used to configure a one-off view controller, having to initialize through the storyboard is essentially use of private implementation details; it shouldn鈥檛 matter whether the VC was designed in code or storyboards, ultimately a single initializer should 鈥渄o the right thing鈥 (just as it does when using XIBs directly). A factory initializer for a View Controller subclass could handle the loading of the storyboard and returning the appropriate view controller.

Here are some comments from the previous thread that I believe are still relevant:

On Dec 9, 2015, at 1:06 PM, Philippe Hausler <phausler@apple.com> wrote:

I can definitely attest that in implementing Foundation we could have much more idiomatic swift and much more similar behavior to the way Foundation on Darwin actually works if we had factory initializers.

On Dec 7, 2015, at 5:24 PM, Brent Royal-Gordon <brent@architechies.com> wrote:

A `protocol init` in a protocol extension creates an initializer which is *not* applied to types conforming to the protocol. Instead, it is actually an initializer on the protocol itself. `self` is the protocol metatype, not an instance of anything. The provided implementation should `return` an instance conforming to (and implicitly casted to) the protocol. Just like any other initializer, a `protocol init` can be failable or throwing.

Unlike other initializers, Swift usually won鈥檛 be able to tell at compile time which concrete type will be returned by a protocol init(), reducing opportunities to statically bind methods and perform other optimization tricks. Frankly, though, that鈥檚 just the cost of doing business. If you want to select a type dynamically, you鈥檙e going to lose the ability to aggressively optimize calls to the resulting instance.

I鈥檇 love to hear everyone鈥檚 thoughts on this!

Best,
Riley Testut
_______________________________________________
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
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

1 Like

What's the motivation behind using `return` rather than self-assignment, like we currently have in inits for structs/enums and protocol extensions?

From the original discussion, it seemed the general consensus was that returning a value felt more natural than assigning to self. Here are some snippets from the original discussion:

Myself:

I鈥檓 not opposed to assigning to self directly in convenience initializers (especially if there is already support for it in the ABI). My only concern would be that it feels less 鈥渘atural鈥 to do so than to simply return a value from the initializer. That being said, I think that鈥檚 a very negligible disadvantage (if even that), and if assigning to self is the easiest way to pull this off, I鈥檓 all for it.

Dave Abrahams:

My instinct agrees with that. Also, reassigning self raises the question of whether an object is allocated (and partly initialized?) before the reassignment. Even if we can answer those questions in some clear way, I鈥檇 rather not have them come up at all.

Stephen Christopher:

I agree. Were I to naively try this in Swift, I would expect to use a convenience initializer and return the instance I鈥檇 created.

Ultimately I'm happy with either returning a value or assigning to self, depending on what the consensus is after a review.

Is the "factory" keyword truly necessary, or could it be implied by "required" and using self-assignment in the init body?

Factory initializers would be closer to convenience initializers rather than required ones, and I think the keyword is semantically useful. Convenience/required initializers are expected to return a type matching that of the static type, while the "factory" keyword signifies that the return value may not match, just be upperbounded by the static type.

Additionally, when dealing with factory initializers in protocol extensions, I think it is much more clear in intent that the function will return a type that conforms to the protocol rather than a hypothetical "instance" of the protocol itself.

路路路

On Mar 17, 2017, at 1:15 PM, Zach Waldowski via swift-evolution <swift-evolution@swift.org> wrote:

Big +1.

Two small nits/questions:

- What's the motivation behind using `return` rather than self-assignment, like we currently have in inits for structs/enums and protocol extensions? I didn't follow the original discussion in depth, so excuse me if this has been hashed out before.
- Is the "factory" keyword truly necessary, or could it be implied by "required" and using self-assignment in the init body?

Best,
聽聽Zachary Waldowski
聽聽zach@waldowski.me

On Fri, Mar 17, 2017, at 12:26 PM, Riley Testut via swift-evolution wrote:

Hi again everyone!

Now that Swift 4 Stage 2 proposals are being considered, I thought it might be time to revisit this proposal and see if it might align with the goals set forth for Swift 4.

As a quick tl;dr, this proposal describes a new "factory initializer" that would allow you to return a value from an initializer. This would have several benefits, as mentioned in the proposal itself as well as throughout this mailing list. For convenience, here's a link to the proposal on GitHub: https://github.com/rileytestut/swift-evolution/blob/master/proposals/NNNN-factory-initializers.md

Would love to hear any more comments on this proposal, and if we feel this is appropriate for considering for Swift 4 I'll happily re-open the pull request!

Riley Testut

On Nov 19, 2016, at 7:45 AM, arkadi daniyelian <arkdan@icloud.com> wrote:
i would appreciate this feature.

For unexperienced developers, its often hard to recognize *when* factory is a good fit to do the job, and how exactly approach the implementation. I imagine having this feature built into the language may help to choose and implement factory when its the right thing to do.

On Nov 18, 2016, at 12:23 AM, Charles Srstka via swift-evolution <swift-evolution@swift.org> wrote:

Is there any chance of reviving this? It seems to me that since this would require Swift initializers to be implemented internally in such a way that they can return a value (as Objective-C init methods do), it may affect ABI stability and thus may be germane to the current stage of Swift 4 development.

Charles

On Dec 17, 2015, at 3:41 PM, Riley Testut via swift-evolution <swift-evolution@swift.org> wrote:

Recently, I proposed the idea of adding the ability to implement the "class cluster" pattern from Cocoa (Touch) in Swift. However, as we discussed it and came up with different approaches, it evolved into a functionality that I believe is far more beneficial to Swift, and subsequently should be the focus of its own proposal. So here is the improved (pre-)proposal:

# Factory Initializers

The "factory" pattern is common in many languages, including Objective-C. Essentially, instead of initializing a type directly, a method is called that returns an instance of the appropriate type determined by the input parameters. Functionally this works well, but ultimately it forces the client of the API to remember to call the factory method instead, rather than the type's initializer. This might seem like a minor gripe, but given that we want Swift to be as approachable as possible to new developers, I think we can do better in this regard.

Rather than have a separate factory method, I propose we build the factory pattern right into Swift, by way of specialized 鈥渇actory initializers鈥. The exact syntax was proposed by Philippe Hausler from the previous thread, and I think it is an excellent solution:

class AbstractBase {
public factory init(type: InformationToSwitchOn) {
聽聽聽聽聽return ConcreteImplementation(type)
}
}

class ConcreteImplementation : AbstractBase {

}

Why exactly would this be useful in practice? In my own development, I鈥檝e come across a few places where this would especially be relevant:

## Class Cluster/Abstract Classes
This was the reasoning behind the original proposal, and I still think it would be a very valid use case. The public superclass would declare all the public methods, and could delegate off the specific implementations to the private subclasses. Alternatively, this method could be used as an easy way to handle backwards-compatibility: rather than litter the code with branches depending on the OS version, simply return the OS-appropriate subclass from the factory initializer. Very useful.

## Protocol Initializers
Proposed by Brent Royal-Gordon, we could use factory initializers with protocol extensions to return the appropriate instance conforming to a protocol for the given needs. Similar to the class cluster/abstract class method, but can work with structs too. This would be closer to the factory method pattern, since you don鈥檛 need to know exactly what type is returned, just the protocol it conforms to.

## Initializing Storyboard-backed View Controller
This is more specific to Apple Frameworks, but having factory initializers could definitely help here. Currently, view controllers associated with a storyboard must be initialized from the client through a factory method on the storyboard instance (storyboard. instantiateViewControllerWithIdentifier()). This works when the entire flow of the app is storyboard based, but when a single storyboard is used to configure a one-off view controller, having to initialize through the storyboard is essentially use of private implementation details; it shouldn鈥檛 matter whether the VC was designed in code or storyboards, ultimately a single initializer should 鈥渄o the right thing鈥 (just as it does when using XIBs directly). A factory initializer for a View Controller subclass could handle the loading of the storyboard and returning the appropriate view controller.

Here are some comments from the previous thread that I believe are still relevant:

On Dec 9, 2015, at 1:06 PM, Philippe Hausler <phausler@apple.com> wrote:

I can definitely attest that in implementing Foundation we could have much more idiomatic swift and much more similar behavior to the way Foundation on Darwin actually works if we had factory initializers.

On Dec 7, 2015, at 5:24 PM, Brent Royal-Gordon <brent@architechies.com> wrote:

A `protocol init` in a protocol extension creates an initializer which is *not* applied to types conforming to the protocol. Instead, it is actually an initializer on the protocol itself. `self` is the protocol metatype, not an instance of anything. The provided implementation should `return` an instance conforming to (and implicitly casted to) the protocol. Just like any other initializer, a `protocol init` can be failable or throwing.

Unlike other initializers, Swift usually won鈥檛 be able to tell at compile time which concrete type will be returned by a protocol init(), reducing opportunities to statically bind methods and perform other optimization tricks. Frankly, though, that鈥檚 just the cost of doing business. If you want to select a type dynamically, you鈥檙e going to lose the ability to aggressively optimize calls to the resulting instance.

I鈥檇 love to hear everyone鈥檚 thoughts on this!

Best,
Riley Testut
_______________________________________________
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

_______________________________________________
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

I'm in favor of this pattern.

路路路

On Mar 20, 2017, at 4:40 PM, Jonathan Hull via swift-evolution <swift-evolution@swift.org> wrote:

Huge +1

On Mar 17, 2017, at 9:26 AM, Riley Testut via swift-evolution <swift-evolution@swift.org> wrote:

Hi again everyone!

Now that Swift 4 Stage 2 proposals are being considered, I thought it might be time to revisit this proposal and see if it might align with the goals set forth for Swift 4.

As a quick tl;dr, this proposal describes a new "factory initializer" that would allow you to return a value from an initializer. This would have several benefits, as mentioned in the proposal itself as well as throughout this mailing list. For convenience, here's a link to the proposal on GitHub: https://github.com/rileytestut/swift-evolution/blob/master/proposals/NNNN-factory-initializers.md

Would love to hear any more comments on this proposal, and if we feel this is appropriate for considering for Swift 4 I'll happily re-open the pull request!

Riley Testut

On Nov 19, 2016, at 7:45 AM, arkadi daniyelian <arkdan@icloud.com> wrote:

i would appreciate this feature.

For unexperienced developers, its often hard to recognize *when* factory is a good fit to do the job, and how exactly approach the implementation. I imagine having this feature built into the language may help to choose and implement factory when its the right thing to do.

On Nov 18, 2016, at 12:23 AM, Charles Srstka via swift-evolution <swift-evolution@swift.org> wrote:

Is there any chance of reviving this? It seems to me that since this would require Swift initializers to be implemented internally in such a way that they can return a value (as Objective-C init methods do), it may affect ABI stability and thus may be germane to the current stage of Swift 4 development.

Charles

On Dec 17, 2015, at 3:41 PM, Riley Testut via swift-evolution <swift-evolution@swift.org> wrote:

Recently, I proposed the idea of adding the ability to implement the "class cluster" pattern from Cocoa (Touch) in Swift. However, as we discussed it and came up with different approaches, it evolved into a functionality that I believe is far more beneficial to Swift, and subsequently should be the focus of its own proposal. So here is the improved (pre-)proposal:

# Factory Initializers

The "factory" pattern is common in many languages, including Objective-C. Essentially, instead of initializing a type directly, a method is called that returns an instance of the appropriate type determined by the input parameters. Functionally this works well, but ultimately it forces the client of the API to remember to call the factory method instead, rather than the type's initializer. This might seem like a minor gripe, but given that we want Swift to be as approachable as possible to new developers, I think we can do better in this regard.

Rather than have a separate factory method, I propose we build the factory pattern right into Swift, by way of specialized 鈥渇actory initializers鈥. The exact syntax was proposed by Philippe Hausler from the previous thread, and I think it is an excellent solution:

class AbstractBase {
public factory init(type: InformationToSwitchOn) {
聽聽聽聽聽return ConcreteImplementation(type)
}
}

class ConcreteImplementation : AbstractBase {

}

Why exactly would this be useful in practice? In my own development, I鈥檝e come across a few places where this would especially be relevant:

## Class Cluster/Abstract Classes
This was the reasoning behind the original proposal, and I still think it would be a very valid use case. The public superclass would declare all the public methods, and could delegate off the specific implementations to the private subclasses. Alternatively, this method could be used as an easy way to handle backwards-compatibility: rather than litter the code with branches depending on the OS version, simply return the OS-appropriate subclass from the factory initializer. Very useful.

## Protocol Initializers
Proposed by Brent Royal-Gordon, we could use factory initializers with protocol extensions to return the appropriate instance conforming to a protocol for the given needs. Similar to the class cluster/abstract class method, but can work with structs too. This would be closer to the factory method pattern, since you don鈥檛 need to know exactly what type is returned, just the protocol it conforms to.

## Initializing Storyboard-backed View Controller
This is more specific to Apple Frameworks, but having factory initializers could definitely help here. Currently, view controllers associated with a storyboard must be initialized from the client through a factory method on the storyboard instance (storyboard. instantiateViewControllerWithIdentifier()). This works when the entire flow of the app is storyboard based, but when a single storyboard is used to configure a one-off view controller, having to initialize through the storyboard is essentially use of private implementation details; it shouldn鈥檛 matter whether the VC was designed in code or storyboards, ultimately a single initializer should 鈥渄o the right thing鈥 (just as it does when using XIBs directly). A factory initializer for a View Controller subclass could handle the loading of the storyboard and returning the appropriate view controller.

Here are some comments from the previous thread that I believe are still relevant:

On Dec 9, 2015, at 1:06 PM, Philippe Hausler <phausler@apple.com> wrote:

I can definitely attest that in implementing Foundation we could have much more idiomatic swift and much more similar behavior to the way Foundation on Darwin actually works if we had factory initializers.

On Dec 7, 2015, at 5:24 PM, Brent Royal-Gordon <brent@architechies.com> wrote:

A `protocol init` in a protocol extension creates an initializer which is *not* applied to types conforming to the protocol. Instead, it is actually an initializer on the protocol itself. `self` is the protocol metatype, not an instance of anything. The provided implementation should `return` an instance conforming to (and implicitly casted to) the protocol. Just like any other initializer, a `protocol init` can be failable or throwing.

Unlike other initializers, Swift usually won鈥檛 be able to tell at compile time which concrete type will be returned by a protocol init(), reducing opportunities to statically bind methods and perform other optimization tricks. Frankly, though, that鈥檚 just the cost of doing business. If you want to select a type dynamically, you鈥檙e going to lose the ability to aggressively optimize calls to the resulting instance.

I鈥檇 love to hear everyone鈥檚 thoughts on this!

Best,
Riley Testut
_______________________________________________
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

_______________________________________________
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

I just have to ask: why should a factory method be part of the language?

I have nothing against it, I am just wondering if I am missing something.
The way I see it everyone can add a factory initializer if he/she needs it. Why make it part of the language?

Regards,
Rien

Site: http://balancingrock.nl
Blog: http://swiftrien.blogspot.com
Github: http://github.com/Balancingrock
Project: http://swiftfire.nl

路路路

On 20 Mar 2017, at 21:40, Jonathan Hull via swift-evolution <swift-evolution@swift.org> wrote:

Huge +1

On Mar 17, 2017, at 9:26 AM, Riley Testut via swift-evolution <swift-evolution@swift.org> wrote:

Hi again everyone!

Now that Swift 4 Stage 2 proposals are being considered, I thought it might be time to revisit this proposal and see if it might align with the goals set forth for Swift 4.

As a quick tl;dr, this proposal describes a new "factory initializer" that would allow you to return a value from an initializer. This would have several benefits, as mentioned in the proposal itself as well as throughout this mailing list. For convenience, here's a link to the proposal on GitHub: https://github.com/rileytestut/swift-evolution/blob/master/proposals/NNNN-factory-initializers.md

Would love to hear any more comments on this proposal, and if we feel this is appropriate for considering for Swift 4 I'll happily re-open the pull request!

Riley Testut

On Nov 19, 2016, at 7:45 AM, arkadi daniyelian <arkdan@icloud.com> wrote:

i would appreciate this feature.

For unexperienced developers, its often hard to recognize *when* factory is a good fit to do the job, and how exactly approach the implementation. I imagine having this feature built into the language may help to choose and implement factory when its the right thing to do.

On Nov 18, 2016, at 12:23 AM, Charles Srstka via swift-evolution <swift-evolution@swift.org> wrote:

Is there any chance of reviving this? It seems to me that since this would require Swift initializers to be implemented internally in such a way that they can return a value (as Objective-C init methods do), it may affect ABI stability and thus may be germane to the current stage of Swift 4 development.

Charles

On Dec 17, 2015, at 3:41 PM, Riley Testut via swift-evolution <swift-evolution@swift.org> wrote:

Recently, I proposed the idea of adding the ability to implement the "class cluster" pattern from Cocoa (Touch) in Swift. However, as we discussed it and came up with different approaches, it evolved into a functionality that I believe is far more beneficial to Swift, and subsequently should be the focus of its own proposal. So here is the improved (pre-)proposal:

# Factory Initializers

The "factory" pattern is common in many languages, including Objective-C. Essentially, instead of initializing a type directly, a method is called that returns an instance of the appropriate type determined by the input parameters. Functionally this works well, but ultimately it forces the client of the API to remember to call the factory method instead, rather than the type's initializer. This might seem like a minor gripe, but given that we want Swift to be as approachable as possible to new developers, I think we can do better in this regard.

Rather than have a separate factory method, I propose we build the factory pattern right into Swift, by way of specialized 鈥渇actory initializers鈥. The exact syntax was proposed by Philippe Hausler from the previous thread, and I think it is an excellent solution:

class AbstractBase {
public factory init(type: InformationToSwitchOn) {
聽聽聽聽聽return ConcreteImplementation(type)
}
}

class ConcreteImplementation : AbstractBase {

}

Why exactly would this be useful in practice? In my own development, I鈥檝e come across a few places where this would especially be relevant:

## Class Cluster/Abstract Classes
This was the reasoning behind the original proposal, and I still think it would be a very valid use case. The public superclass would declare all the public methods, and could delegate off the specific implementations to the private subclasses. Alternatively, this method could be used as an easy way to handle backwards-compatibility: rather than litter the code with branches depending on the OS version, simply return the OS-appropriate subclass from the factory initializer. Very useful.

## Protocol Initializers
Proposed by Brent Royal-Gordon, we could use factory initializers with protocol extensions to return the appropriate instance conforming to a protocol for the given needs. Similar to the class cluster/abstract class method, but can work with structs too. This would be closer to the factory method pattern, since you don鈥檛 need to know exactly what type is returned, just the protocol it conforms to.

## Initializing Storyboard-backed View Controller
This is more specific to Apple Frameworks, but having factory initializers could definitely help here. Currently, view controllers associated with a storyboard must be initialized from the client through a factory method on the storyboard instance (storyboard. instantiateViewControllerWithIdentifier()). This works when the entire flow of the app is storyboard based, but when a single storyboard is used to configure a one-off view controller, having to initialize through the storyboard is essentially use of private implementation details; it shouldn鈥檛 matter whether the VC was designed in code or storyboards, ultimately a single initializer should 鈥渄o the right thing鈥 (just as it does when using XIBs directly). A factory initializer for a View Controller subclass could handle the loading of the storyboard and returning the appropriate view controller.

Here are some comments from the previous thread that I believe are still relevant:

On Dec 9, 2015, at 1:06 PM, Philippe Hausler <phausler@apple.com> wrote:

I can definitely attest that in implementing Foundation we could have much more idiomatic swift and much more similar behavior to the way Foundation on Darwin actually works if we had factory initializers.

On Dec 7, 2015, at 5:24 PM, Brent Royal-Gordon <brent@architechies.com> wrote:

A `protocol init` in a protocol extension creates an initializer which is *not* applied to types conforming to the protocol. Instead, it is actually an initializer on the protocol itself. `self` is the protocol metatype, not an instance of anything. The provided implementation should `return` an instance conforming to (and implicitly casted to) the protocol. Just like any other initializer, a `protocol init` can be failable or throwing.

Unlike other initializers, Swift usually won鈥檛 be able to tell at compile time which concrete type will be returned by a protocol init(), reducing opportunities to statically bind methods and perform other optimization tricks. Frankly, though, that鈥檚 just the cost of doing business. If you want to select a type dynamically, you鈥檙e going to lose the ability to aggressively optimize calls to the resulting instance.

I鈥檇 love to hear everyone鈥檚 thoughts on this!

Best,
Riley Testut
_______________________________________________
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

_______________________________________________
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

+ IntMax.max

路路路

On Tue, Mar 21, 2017 at 12:07 PM, Greg Parker via swift-evolution < swift-evolution@swift.org> wrote:

On Mar 17, 2017, at 9:26 AM, Riley Testut via swift-evolution < > swift-evolution@swift.org> wrote:

Hi again everyone!

Now that Swift 4 Stage 2 proposals are being considered, I thought it
might be time to revisit this proposal and see if it might align with the
goals set forth for Swift 4.

As a quick tl;dr, this proposal describes a new "factory initializer" that
would allow you to return a value from an initializer. This would have
several benefits, as mentioned in the proposal itself as well as throughout
this mailing list. For convenience, here's a link to the proposal on
GitHub: https://github.com/rileytestut/swift-evolution/
blob/master/proposals/NNNN-factory-initializers.md

Would love to hear any more comments on this proposal, and if we feel this
is appropriate for considering for Swift 4 I'll happily re-open the pull
request!

"As for overriding, just like convenience initializers, factory
initializers should not be able to be overridden by subclasses."

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?

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?

--
Greg Parker gparker@apple.com Runtime Wrangler

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

There are several reasons. It is a very common pattern in ObjC/Cocoa. For example, they allow class clusters (and the protocol equivalent).

One of the Apple foundation people replied earlier in this thread that it would allow them to remove several hacks from the foundation overlays, and improve safety.

One of the ideas I am most excited about is the ability for a protocol to provide default conformances. For example, I have an Expression protocol to represent mathematical expressions, and I have a few basic conforming structs representing constants, variables, and some basic operations. With a factory method, I can say 鈥楨xpression(2)鈥 or 鈥楨xpression(鈥淰arName鈥)鈥 and have it create the correct conformance. My conforming structs can even be private, if I want this to be the only way they are created.

If I have expensive-to-create immutable objects where I am creating equivalent values all the time, I can store commonly created values in a cache and return the cached versions (instead of creating an instance). I believe cocoa used to do this with NSNumbers before tagged pointers became a thing.

Or, I could return something which is lazily created.

Longer term (once reflection has improved), I have a proposal to allow extensible factory methods. We talked about it during the original discussion, but the gist is that there would be way to get a list of all types conforming to a protocol (or all subclasses of a class) from the compiler, and then you could use static methods to query those types until you found one which has the properties you are looking for, and then instantiate and return it. The end result is that you have a factory initializer where new conformances (even from plug-ins) can participate and be returned when appropriate. This proposal is a necessary first step to that.

As a concrete use-case of that extension, I have been experimenting for years with auto-creating UI to edit structured data (e.g. JSON or Plists) or objects. This is fairly easy in ObjC, but it is only possible in Swift in a very limited way at the moment. With the above extension and key paths, I should be able to recreate my ObjC interfaces in a nicer/swiftier way.

Those are just a few of the uses.

Thanks,
Jon

路路路

On Mar 21, 2017, at 8:49 AM, David R枚nnqvist via swift-evolution <swift-evolution@swift.org> wrote:

Forgive me if that has already been discussed in the email threads prior to the proposal, but what I鈥檓 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 acknowledge that it鈥檚 a common pattern in many languages, but don鈥檛 find it a very strong argument as to why it should be built into the language.

Regards,
David

On 17 Mar 2017, at 17:26, Riley Testut via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Hi again everyone!

Now that Swift 4 Stage 2 proposals are being considered, I thought it might be time to revisit this proposal and see if it might align with the goals set forth for Swift 4.

As a quick tl;dr, this proposal describes a new "factory initializer" that would allow you to return a value from an initializer. This would have several benefits, as mentioned in the proposal itself as well as throughout this mailing list. For convenience, here's a link to the proposal on GitHub: https://github.com/rileytestut/swift-evolution/blob/master/proposals/NNNN-factory-initializers.md

Would love to hear any more comments on this proposal, and if we feel this is appropriate for considering for Swift 4 I'll happily re-open the pull request!

Riley Testut

On Nov 19, 2016, at 7:45 AM, arkadi daniyelian <arkdan@icloud.com <mailto:arkdan@icloud.com>> wrote:

i would appreciate this feature.

For unexperienced developers, its often hard to recognize *when* factory is a good fit to do the job, and how exactly approach the implementation. I imagine having this feature built into the language may help to choose and implement factory when its the right thing to do.

On Nov 18, 2016, at 12:23 AM, Charles Srstka via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Is there any chance of reviving this? It seems to me that since this would require Swift initializers to be implemented internally in such a way that they can return a value (as Objective-C init methods do), it may affect ABI stability and thus may be germane to the current stage of Swift 4 development.

Charles

On Dec 17, 2015, at 3:41 PM, Riley Testut via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Recently, I proposed the idea of adding the ability to implement the "class cluster" pattern from Cocoa (Touch) in Swift. However, as we discussed it and came up with different approaches, it evolved into a functionality that I believe is far more beneficial to Swift, and subsequently should be the focus of its own proposal. So here is the improved (pre-)proposal:

# Factory Initializers

The "factory" pattern is common in many languages, including Objective-C. Essentially, instead of initializing a type directly, a method is called that returns an instance of the appropriate type determined by the input parameters. Functionally this works well, but ultimately it forces the client of the API to remember to call the factory method instead, rather than the type's initializer. This might seem like a minor gripe, but given that we want Swift to be as approachable as possible to new developers, I think we can do better in this regard.

Rather than have a separate factory method, I propose we build the factory pattern right into Swift, by way of specialized 鈥渇actory initializers鈥. The exact syntax was proposed by Philippe Hausler from the previous thread, and I think it is an excellent solution:

class AbstractBase {
public factory init(type: InformationToSwitchOn) {
聽聽聽聽聽return ConcreteImplementation(type)
}
}

class ConcreteImplementation : AbstractBase {

}

Why exactly would this be useful in practice? In my own development, I鈥檝e come across a few places where this would especially be relevant:

## Class Cluster/Abstract Classes
This was the reasoning behind the original proposal, and I still think it would be a very valid use case. The public superclass would declare all the public methods, and could delegate off the specific implementations to the private subclasses. Alternatively, this method could be used as an easy way to handle backwards-compatibility: rather than litter the code with branches depending on the OS version, simply return the OS-appropriate subclass from the factory initializer. Very useful.

## Protocol Initializers
Proposed by Brent Royal-Gordon, we could use factory initializers with protocol extensions to return the appropriate instance conforming to a protocol for the given needs. Similar to the class cluster/abstract class method, but can work with structs too. This would be closer to the factory method pattern, since you don鈥檛 need to know exactly what type is returned, just the protocol it conforms to.

## Initializing Storyboard-backed View Controller
This is more specific to Apple Frameworks, but having factory initializers could definitely help here. Currently, view controllers associated with a storyboard must be initialized from the client through a factory method on the storyboard instance (storyboard. instantiateViewControllerWithIdentifier()). This works when the entire flow of the app is storyboard based, but when a single storyboard is used to configure a one-off view controller, having to initialize through the storyboard is essentially use of private implementation details; it shouldn鈥檛 matter whether the VC was designed in code or storyboards, ultimately a single initializer should 鈥渄o the right thing鈥 (just as it does when using XIBs directly). A factory initializer for a View Controller subclass could handle the loading of the storyboard and returning the appropriate view controller.

Here are some comments from the previous thread that I believe are still relevant:

On Dec 9, 2015, at 1:06 PM, Philippe Hausler <phausler@apple.com <mailto:phausler@apple.com>> wrote:

I can definitely attest that in implementing Foundation we could have much more idiomatic swift and much more similar behavior to the way Foundation on Darwin actually works if we had factory initializers.

On Dec 7, 2015, at 5:24 PM, Brent Royal-Gordon <brent@architechies.com <mailto:brent@architechies.com>> wrote:

A `protocol init` in a protocol extension creates an initializer which is *not* applied to types conforming to the protocol. Instead, it is actually an initializer on the protocol itself. `self` is the protocol metatype, not an instance of anything. The provided implementation should `return` an instance conforming to (and implicitly casted to) the protocol. Just like any other initializer, a `protocol init` can be failable or throwing.

Unlike other initializers, Swift usually won鈥檛 be able to tell at compile time which concrete type will be returned by a protocol init(), reducing opportunities to statically bind methods and perform other optimization tricks. Frankly, though, that鈥檚 just the cost of doing business. If you want to select a type dynamically, you鈥檙e going to lose the ability to aggressively optimize calls to the resulting instance.

I鈥檇 love to hear everyone鈥檚 thoughts on this!

Best,
Riley Testut
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

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

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto: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

I believe that this proposal is trying to solve something that can be solved by allowing assignment to self within convenience initializers.

Unfortunately, even convenience initializers are allocating which makes it harder to achieve with backward compatibility - though I'm not entirely sure what would be the consequences of turning them into non-allocating.

If it's not possible due to implementational details, I'd suggest to rather introduce a @nonallocating (or similar) annotation (keyword?) that can be placed on init methods and it would then require for self to be assigned during the initialization as long as the assigned value is subtype of the receiver:

@nonallocating init(x: Int) {
聽聽if x < 0 {
聽聽聽聽self = NegativeMe(x: x)
聽聽} else {
聽聽聽聽self = PositiveMe(x: x)
聽聽}
}

Which is pretty much what the proposal is suggesting, but removes the "factory" keyword which may be a bit misleading or narrowly named.

路路路

On Mar 21, 2017, at 4:49 PM, David R枚nnqvist via swift-evolution <swift-evolution@swift.org> wrote:

Forgive me if that has already been discussed in the email threads prior to the proposal, but what I鈥檓 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 acknowledge that it鈥檚 a common pattern in many languages, but don鈥檛 find it a very strong argument as to why it should be built into the language.

Regards,
David

On 17 Mar 2017, at 17:26, Riley Testut via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Hi again everyone!

Now that Swift 4 Stage 2 proposals are being considered, I thought it might be time to revisit this proposal and see if it might align with the goals set forth for Swift 4.

As a quick tl;dr, this proposal describes a new "factory initializer" that would allow you to return a value from an initializer. This would have several benefits, as mentioned in the proposal itself as well as throughout this mailing list. For convenience, here's a link to the proposal on GitHub: https://github.com/rileytestut/swift-evolution/blob/master/proposals/NNNN-factory-initializers.md

Would love to hear any more comments on this proposal, and if we feel this is appropriate for considering for Swift 4 I'll happily re-open the pull request!

Riley Testut

On Nov 19, 2016, at 7:45 AM, arkadi daniyelian <arkdan@icloud.com <mailto:arkdan@icloud.com>> wrote:

i would appreciate this feature.

For unexperienced developers, its often hard to recognize *when* factory is a good fit to do the job, and how exactly approach the implementation. I imagine having this feature built into the language may help to choose and implement factory when its the right thing to do.

On Nov 18, 2016, at 12:23 AM, Charles Srstka via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Is there any chance of reviving this? It seems to me that since this would require Swift initializers to be implemented internally in such a way that they can return a value (as Objective-C init methods do), it may affect ABI stability and thus may be germane to the current stage of Swift 4 development.

Charles

On Dec 17, 2015, at 3:41 PM, Riley Testut via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Recently, I proposed the idea of adding the ability to implement the "class cluster" pattern from Cocoa (Touch) in Swift. However, as we discussed it and came up with different approaches, it evolved into a functionality that I believe is far more beneficial to Swift, and subsequently should be the focus of its own proposal. So here is the improved (pre-)proposal:

# Factory Initializers

The "factory" pattern is common in many languages, including Objective-C. Essentially, instead of initializing a type directly, a method is called that returns an instance of the appropriate type determined by the input parameters. Functionally this works well, but ultimately it forces the client of the API to remember to call the factory method instead, rather than the type's initializer. This might seem like a minor gripe, but given that we want Swift to be as approachable as possible to new developers, I think we can do better in this regard.

Rather than have a separate factory method, I propose we build the factory pattern right into Swift, by way of specialized 鈥渇actory initializers鈥. The exact syntax was proposed by Philippe Hausler from the previous thread, and I think it is an excellent solution:

class AbstractBase {
public factory init(type: InformationToSwitchOn) {
聽聽聽聽聽return ConcreteImplementation(type)
}
}

class ConcreteImplementation : AbstractBase {

}

Why exactly would this be useful in practice? In my own development, I鈥檝e come across a few places where this would especially be relevant:

## Class Cluster/Abstract Classes
This was the reasoning behind the original proposal, and I still think it would be a very valid use case. The public superclass would declare all the public methods, and could delegate off the specific implementations to the private subclasses. Alternatively, this method could be used as an easy way to handle backwards-compatibility: rather than litter the code with branches depending on the OS version, simply return the OS-appropriate subclass from the factory initializer. Very useful.

## Protocol Initializers
Proposed by Brent Royal-Gordon, we could use factory initializers with protocol extensions to return the appropriate instance conforming to a protocol for the given needs. Similar to the class cluster/abstract class method, but can work with structs too. This would be closer to the factory method pattern, since you don鈥檛 need to know exactly what type is returned, just the protocol it conforms to.

## Initializing Storyboard-backed View Controller
This is more specific to Apple Frameworks, but having factory initializers could definitely help here. Currently, view controllers associated with a storyboard must be initialized from the client through a factory method on the storyboard instance (storyboard. instantiateViewControllerWithIdentifier()). This works when the entire flow of the app is storyboard based, but when a single storyboard is used to configure a one-off view controller, having to initialize through the storyboard is essentially use of private implementation details; it shouldn鈥檛 matter whether the VC was designed in code or storyboards, ultimately a single initializer should 鈥渄o the right thing鈥 (just as it does when using XIBs directly). A factory initializer for a View Controller subclass could handle the loading of the storyboard and returning the appropriate view controller.

Here are some comments from the previous thread that I believe are still relevant:

On Dec 9, 2015, at 1:06 PM, Philippe Hausler <phausler@apple.com <mailto:phausler@apple.com>> wrote:

I can definitely attest that in implementing Foundation we could have much more idiomatic swift and much more similar behavior to the way Foundation on Darwin actually works if we had factory initializers.

On Dec 7, 2015, at 5:24 PM, Brent Royal-Gordon <brent@architechies.com <mailto:brent@architechies.com>> wrote:

A `protocol init` in a protocol extension creates an initializer which is *not* applied to types conforming to the protocol. Instead, it is actually an initializer on the protocol itself. `self` is the protocol metatype, not an instance of anything. The provided implementation should `return` an instance conforming to (and implicitly casted to) the protocol. Just like any other initializer, a `protocol init` can be failable or throwing.

Unlike other initializers, Swift usually won鈥檛 be able to tell at compile time which concrete type will be returned by a protocol init(), reducing opportunities to statically bind methods and perform other optimization tricks. Frankly, though, that鈥檚 just the cost of doing business. If you want to select a type dynamically, you鈥檙e going to lose the ability to aggressively optimize calls to the resulting instance.

I鈥檇 love to hear everyone鈥檚 thoughts on this!

Best,
Riley Testut
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

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

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto: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