Strong +1 on this, particularly on the part about protocol initializers. This 
would bring together some of the best aspects of both Objective-C class 
clusters and Swift protocol-oriented programming and would be a huge benefit to 
application developers.

Charles

> On Dec 17, 2015, at 3:41 PM, Riley Testut via swift-evolution 
> <[email protected]> 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 “factory 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’ve 
> 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’t 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’t 
> matter whether the VC was designed in code or storyboards, ultimately a 
> single initializer should “do 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 <[email protected]> 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 <[email protected]> 
>> 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’t 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’s just the cost of doing business. If you want 
>> to select a type dynamically, you’re going to lose the ability to 
>> aggressively optimize calls to the resulting instance.
>> 
> 
> 
> I’d love to hear everyone’s thoughts on this!
> 
> Best,
> Riley Testut
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to