Hey all!

Just updated the proposal with all the recent changes, and you can check it 
here: 
https://github.com/rileytestut/swift-evolution/blob/master/proposals/NNNN-factory-initializers.md
 
<https://github.com/rileytestut/swift-evolution/blob/master/proposals/NNNN-factory-initializers.md>

Planning on submitting the PR later tonight, so please let me know if you have 
any last minute feedback!
Riley

> On Mar 30, 2016, at 1:35 PM, Jonathan Hull <[email protected]> wrote:
> 
> Probably ‘no' in this proposal to keep things simple.
> 
> Long term, I would like overriding of the factory init to be the mechanism 
> for a post-hoc extendable factory.  Disallowing it now probably makes that 
> easier in the future.
> 
> Thanks,
> Jon
> 
> 
>> On Mar 30, 2016, at 1:20 PM, Riley Testut <[email protected] 
>> <mailto:[email protected]>> wrote:
>> 
>> Another point to consider: should factory initializers be able to be 
>> overridden by subclasses? I vote no, just as you can't override convenience 
>> initializers.
>> 
>> On Mar 30, 2016, at 3:50 AM, Jonathan Hull <[email protected] 
>> <mailto:[email protected]>> wrote:
>> 
>>> Yeah.  I was thinking we would want to mirror the convenience initializer 
>>> syntax, but I am completely ok with this as well.  Honestly this is the 
>>> syntax I first tried to use in convenience inits while learning swift, and 
>>> I would love to see that migrate to something like this.  My only worry 
>>> would be that people would be confused on when to use ClassName() and when 
>>> to use self.init().  Best to choose one and stick with it.
>>> 
>>> Thanks,
>>> Jon
>>> 
>>>> On Mar 30, 2016, at 3:36 AM, Riley Testut <[email protected] 
>>>> <mailto:[email protected]>> wrote:
>>>> 
>>>> If we are to enforce a different type signature for factory initializers 
>>>> vs required/convenience initializers (which would greatly simplify this 
>>>> issue), if I’m understanding correctly, there shouldn’t be a need to be 
>>>> able to “return” self.init(), right? Because you could do this instead:
>>>> 
>>>> public class ConcreteBase {
>>>> 
>>>>    private init(type2: InformationToSwitchOn) {
>>>>            //Default implementation here
>>>>    }
>>>> 
>>>>    public factory init (type: InformationToSwitchOn) {
>>>>            if … {
>>>>                    return SpecialSubclass(type)  //Handle a special case 
>>>> with a more efficient implementation
>>>>            }
>>>>            return ConcreteBase(type) //Handle the general case with the 
>>>> main class
>>>>    }
>>>> }
>>>> 
>>>> class SpecialSubclass : ConcreteBase {}
>>>> 
>>>>> On Mar 30, 2016, at 3:30 AM, Jonathan Hull <[email protected] 
>>>>> <mailto:[email protected]>> wrote:
>>>>> 
>>>>> Doh!  
>>>>> 
>>>>> Sorry, typed that up in mail while working on something else at the same 
>>>>> time.  We shouldn’t allow an init with the same signature.  self.init() 
>>>>> could be called with different parameters.  Trying to call the factory 
>>>>> method from the factory method should generate an error.
>>>>> 
>>>>> We probably also want to disallow having an init with the same signature 
>>>>> in subclasses as well (we could pass the same info with different 
>>>>> parameter names) as a subclass which doesn’t override it would again be 
>>>>> calling the factory method.  Ultimately, I would like to see the ability 
>>>>> to override the factory method with the behavior I described earlier… but 
>>>>> that is for a later proposal.
>>>>> 
>>>>> Basically we should be able to return anything which adheres to the type, 
>>>>> so we are free to use other initializers on the class/subclasses.
>>>>> 
>>>>> Thanks,
>>>>> Jon
>>>>> 
>>>>> 
>>>>>> On Mar 30, 2016, at 3:10 AM, Riley Testut <[email protected] 
>>>>>> <mailto:[email protected]>> wrote:
>>>>>> 
>>>>>> Ah, good catch. Would that be confusing as to whether self.init() would 
>>>>>> lead to an infinite loop, or call the required initializer? Unlike 
>>>>>> convenience initializers, factory initializers might have the same 
>>>>>> signature as the required ones.
>>>>>> 
>>>>>>> On Mar 30, 2016, at 2:52 AM, Jonathan Hull <[email protected] 
>>>>>>> <mailto:[email protected]>> wrote:
>>>>>>> 
>>>>>>> Agreed.  I would like to see what I was referring to as “stage 1” in 
>>>>>>> this proposal, and we can (hopefully) add on a full solution over time. 
>>>>>>>  (I just wanted to make sure we considered those cases so we didn’t 
>>>>>>> block future improvements)
>>>>>>> 
>>>>>>> Looking at the proposal, my only contention would be that we should 
>>>>>>> also allow self.init() to be called from the factory init (similar to a 
>>>>>>> convenience init).  It could still be used with an AbstractBase as 
>>>>>>> shown in your example (especially when dealing with protocols), but it 
>>>>>>> shouldn’t force us to be abstract in the class case.
>>>>>>> 
>>>>>>> In other words, we should also be able to do the following:
>>>>>>> 
>>>>>>> public class ConcreteBase {
>>>>>>> 
>>>>>>>         private init(type: InformationToSwitchOn) {
>>>>>>>                 //Default implementation here
>>>>>>>         }
>>>>>>> 
>>>>>>>         public factory init (type: InformationToSwitchOn) {
>>>>>>>                 if … {
>>>>>>>                         return SpecialSubclass(type)  //Handle a 
>>>>>>> special case with a more efficient implementation
>>>>>>>                 }
>>>>>>>                 return self.init(type) //Handle the general case with 
>>>>>>> the main class
>>>>>>>         }
>>>>>>> }
>>>>>>> 
>>>>>>> class SpecialSubclass : ConcreteBase {}
>>>>>>> 
>>>>>>> 
>>>>>>> 
>>>>>>> The behavior should simply be that we can return any init’d object that 
>>>>>>> conforms to the given type.
>>>>>>> 
>>>>>>> Thanks,
>>>>>>> Jon
>>>>>>> 
>>>>>>> 
>>>>>>>> On Mar 30, 2016, at 2:20 AM, Riley Testut <[email protected] 
>>>>>>>> <mailto:[email protected]>> wrote:
>>>>>>>> 
>>>>>>>> Ultimately, while these are good points, I feel the full mechanism for 
>>>>>>>> class clusters belong in a separate proposal. The focus for this one I 
>>>>>>>> believe should be the underlying mechanism of factory initializers; 
>>>>>>>> should that be approved, then we can focus on adding additional 
>>>>>>>> features on top of it.
>>>>>>>> 
>>>>>>>> That being said, I’ve written up essentially a final version of the 
>>>>>>>> proposal, which you can find here: 
>>>>>>>> https://github.com/rileytestut/swift-evolution/blob/master/proposals/NNNN-factory-initializers.md
>>>>>>>>  
>>>>>>>> <https://github.com/rileytestut/swift-evolution/blob/master/proposals/NNNN-factory-initializers.md>.
>>>>>>>>  Assuming everyone is happy with it, I’ll send a pull request in the 
>>>>>>>> next few days to the main-repo. But please, give any last minute 
>>>>>>>> feedback now!
>>>>>>>> 
>>>>>>>>> On Mar 24, 2016, at 5:12 PM, Jonathan Hull <[email protected] 
>>>>>>>>> <mailto:[email protected]>> wrote:
>>>>>>>>> 
>>>>>>>>> Comments inline.
>>>>>>>>> 
>>>>>>>>>> On Mar 24, 2016, at 12:10 AM, Riley Testut <[email protected] 
>>>>>>>>>> <mailto:[email protected]>> wrote:
>>>>>>>>>> 
>>>>>>>>>> While I do believe your proposed additions have their benefits, my 
>>>>>>>>>> gut tells me this is too large a change to Swift for an arguably 
>>>>>>>>>> small gain. For this proposal, I'm wanting to keep the change as 
>>>>>>>>>> minimalistic as possible, while still providing enough flexibility 
>>>>>>>>>> and use cases to warrant it.
>>>>>>>>> 
>>>>>>>>> I can definitely see the argument that extensibility is out of scope 
>>>>>>>>> for Swift 3, but I do want to make sure that it is possible for us to 
>>>>>>>>> have extensibility in the future (that we don’t block ourselves from 
>>>>>>>>> doing it).
>>>>>>>>> 
>>>>>>>>> I strongly disagree that the gain is small.  One of the core benefits 
>>>>>>>>> of both Swift/ObjC (and now POP) is the ability to extend things 
>>>>>>>>> post-hoc, without access to the original code.
>>>>>>>>> 
>>>>>>>>> I often write libraries & SDKs, so the users of my code don't have 
>>>>>>>>> access to the original code.  I guess extensibility is less necessary 
>>>>>>>>> when you control the entire codebase, but you still have to refactor 
>>>>>>>>> your factory whenever you subclass (or adhere to a protocol), which I 
>>>>>>>>> find problematic.
>>>>>>>>> 
>>>>>>>>> This is something I run into a lot while writing actual code, so it 
>>>>>>>>> isn’t just a theoretical concern.
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>>> Interesting you bring up the registering of subclasses, as that is 
>>>>>>>>>> similar to the very original proposal, and actually similar to what 
>>>>>>>>>> I'm doing in my own app. Effectively, I have an Objective-C base 
>>>>>>>>>> class, and in +load it dynamically finds all subclasses using the 
>>>>>>>>>> Objective-C runtime, and stores a reference to them. Then in the 
>>>>>>>>>> initializer, it returns the appropriate subclass based on the 
>>>>>>>>>> initialization parameters. This was my solution to the superclass 
>>>>>>>>>> not having to explicitly know each individual subclass.
>>>>>>>>>> 
>>>>>>>>>> Using factory initializers, however, this pattern could be used in 
>>>>>>>>>> pure Swift, albeit with some minor modifications. At program start, 
>>>>>>>>>> the program could register subclasses with the superclass, and then 
>>>>>>>>>> in the initializer would simply return the appropriate subclass 
>>>>>>>>>> (similar to NSURLProtocol, I believe).
>>>>>>>>> 
>>>>>>>>> Yes, I have also used load in this way in ObjC.  In Swift, I think 
>>>>>>>>> the compiler could easily build an array/table of the overloads of 
>>>>>>>>> factory inits.  This avoids having to register explicitly (the 
>>>>>>>>> declaration itself implies intent to register), and doesn’t take up 
>>>>>>>>> any cycles during execution.
>>>>>>>>> 
>>>>>>>>> I ran into the problem of when to register the other day in a current 
>>>>>>>>> project, as Swift doesn’t have an equivalent to +load that I am aware 
>>>>>>>>> of.  I had to settle for something of a hack which gets called on 
>>>>>>>>> first use… but it was only a partial solution which worked in that 
>>>>>>>>> particular case.  How do the swift classes/enums/structs get called 
>>>>>>>>> to register themselves?
>>>>>>>>> 
>>>>>>>>> We may want to propose adding a +load equivalent for Swift types, 
>>>>>>>>> since it does come up occasionally. It is one of those things which 
>>>>>>>>> you don’t need often, but when you do, you really need it.  
>>>>>>>>> Ironically, this was one of the uses of the original feature I talked 
>>>>>>>>> about earlier (we used it to provide the equivalent of +load, 
>>>>>>>>> awakeFromNib, etc… in the language). 
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>>> As for rationale for protocol (factory) initializers, a common 
>>>>>>>>>> pattern I've come across when developing my internal frameworks is 
>>>>>>>>>> to design a protocol, and then to provide a default implementation 
>>>>>>>>>> of the protocol with a type (typically a struct). I feel this 
>>>>>>>>>> relationship could be bridged easier by simply returning this type 
>>>>>>>>>> from a protocol initializer, which could even potentially allow me 
>>>>>>>>>> to declare the actual type as private, so for all intents and 
>>>>>>>>>> purposes the client does simply get an initialized protocol object 
>>>>>>>>>> (similar in part to creating an anonymous class conforming to a 
>>>>>>>>>> protocol in Java).
>>>>>>>>> 
>>>>>>>>> I strongly agree that we should have factory initializers for 
>>>>>>>>> protocols for the reasons you state here, plus many others.  It just 
>>>>>>>>> seems like a natural fit.
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> I would like to see a 3 stage approach:
>>>>>>>>> 
>>>>>>>>> Stage 1:  Declaring an init as “factory” allows you to return any 
>>>>>>>>> fully inited object which fits the type (including calling self.init 
>>>>>>>>> like a convenience init would and then returning it). If the init is 
>>>>>>>>> failable, you can also return nil.  This works both on classes and 
>>>>>>>>> protocols.
>>>>>>>>> 
>>>>>>>>> Stage 2:  The compiler builds a table of the overrides of a given 
>>>>>>>>> factory init, and there is some syntax to call them (e.g. “let sub = 
>>>>>>>>> subclasses.init(value)”) such that the first one to return non-nil is 
>>>>>>>>> the return value to that call.  Thorsten’s depth first + alphabetical 
>>>>>>>>> ordering would be adequate to make the behavior predictable.  Again, 
>>>>>>>>> this should work for both classes and protocols. (I am open to better 
>>>>>>>>> ideas for syntax/naming)
>>>>>>>>> 
>>>>>>>>> Stage 3: We allow greater control over the ordering in the table. 
>>>>>>>>> This still needs thought both on syntax and method.  Something 
>>>>>>>>> similar to operator precedence (or autolayout priority) would work in 
>>>>>>>>> a pinch, but isn’t super elegant. In practice, it might be enough 
>>>>>>>>> just to be able to declare that something needs to be before/after a 
>>>>>>>>> specific subclass in the list.
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> Note: A slightly different approach to stage 2 (for classes) might 
>>>>>>>>> have only the direct subclasses in the table, and then the subclasses 
>>>>>>>>> have the option to call off to their own subclasses in the same 
>>>>>>>>> manner if desired.  This has the tradeoff that each level needs to 
>>>>>>>>> plan for extensibility (i.e. you can’t override something which 
>>>>>>>>> wasn’t expecting to be subclassed), but I do like how it simplifies 
>>>>>>>>> the model a bit.
>>>>>>>>> 
>>>>>>>>> I have a feeling that the proper syntax for stages 2/3 may become 
>>>>>>>>> more obvious once the design work around mixins/protocols+storage 
>>>>>>>>> gets done.  It may just fall out of the disambiguation syntax...
>>>>>>>>> 
>>>>>>>>> Thanks,
>>>>>>>>> Jon
>>>>>>>>> 
>>>>>>>>>> On Mar 22, 2016, at 5:21 PM, Jonathan Hull <[email protected] 
>>>>>>>>>> <mailto:[email protected]>> wrote:
>>>>>>>>>> 
>>>>>>>>>>> 
>>>>>>>>>>> Yes and No.
>>>>>>>>>>> Yes, because this is a problem I run into all the time, and I 
>>>>>>>>>>> really want swift to have a solution for it. I especially like 
>>>>>>>>>>> Brent’s idea of a protocol init.
>>>>>>>>>>> No, because I have gotten a bit greedy. I want us to take a step 
>>>>>>>>>>> back and look at the underlying problem to see if we can come up 
>>>>>>>>>>> with something which completely solves it… and I think factories 
>>>>>>>>>>> get us only part way there. Let’s take a moment and see if we can 
>>>>>>>>>>> create something uniquely swift before we copy/paste existing 
>>>>>>>>>>> solutions.
>>>>>>>>>>> Think about Cocoa’s class clusters for a moment. I love them, but 
>>>>>>>>>>> they are a pain to subclass. To the level where any beginning Cocoa 
>>>>>>>>>>> instruction tells you explicitly not to subclass them. Similarly, 
>>>>>>>>>>> even in my own factories, they are always a pain to extend.
>>>>>>>>>>> I want our factory inits to be extensible by default.
>>>>>>>>>>> 
>>>>>>>>>>> By extensible, I mean that I want to be able to add a new subclass 
>>>>>>>>>>> (or a new entity satisfying a protocol), and have it come out of 
>>>>>>>>>>> the factory when appropriate without editing the base class! 
>>>>>>>>>>> Madness, I know, but:
>>>>>>>>>>> 1) I may not have access to the source of the base class (e.g. 
>>>>>>>>>>> Cocoa Collections)
>>>>>>>>>>> 2) I always feel a bit dirty giving the base class knowledge of 
>>>>>>>>>>> it’s subclasses
>>>>>>>>>>> 3) It is a royal pain, and a potential source of errors as things 
>>>>>>>>>>> get refactored when adding new subclasses
>>>>>>>>>>> 
>>>>>>>>>>> I think I have at least the seed of an idea of how to solve this, 
>>>>>>>>>>> and I am hoping that one of you (who are all much smarter than I) 
>>>>>>>>>>> might have the key to getting it the rest of the way.
>>>>>>>>>>> I ran into this problem again last week, and it made me think of an 
>>>>>>>>>>> old language I used to use...
>>>>>>>>>>> There was a small programming language I used to use in the 90’s 
>>>>>>>>>>> which had an interesting core language feature we called 
>>>>>>>>>>> “handlers”. These were a lot like registering for notifications, 
>>>>>>>>>>> except that writing a function (with a special “Handler” attribute: 
>>>>>>>>>>> “Handler func myFuncName()") was all you needed to do to register. 
>>>>>>>>>>> Writing “Handle myFuncName()” would then systematically call every 
>>>>>>>>>>> function with that name and the Handler attribute.
>>>>>>>>>>> That is, instead of calling a single function, it would 
>>>>>>>>>>> systematically call a series of functions (all with the same name).
>>>>>>>>>>> There was one other thing that made these handlers special. Each 
>>>>>>>>>>> one had the option, when it was called, to reply that it was the 
>>>>>>>>>>> one true handler, and the others didn’t need to be called. 
>>>>>>>>>>> Basically, it said “I've got this!”. This even allowed it to return 
>>>>>>>>>>> a result to the caller.
>>>>>>>>>>> The original intent of this feature (and why it was a core language 
>>>>>>>>>>> feature) was to handle events. It would handle things like hit 
>>>>>>>>>>> testing and key events fairly elegantly. It was a powerful feature, 
>>>>>>>>>>> so it was quickly used for other things. It made things like 
>>>>>>>>>>> plug-ins ridiculously simple. We even used it for a form of error 
>>>>>>>>>>> handling.
>>>>>>>>>>> I remember helping to write a page layout program in it, and we 
>>>>>>>>>>> used handlers not just for the hit testing, but for the tool 
>>>>>>>>>>> palette as well. The end result was that you were able to add new 
>>>>>>>>>>> shapes and new tools without modifying existing code at all. It is 
>>>>>>>>>>> a feature I miss all the time...
>>>>>>>>>>> 
>>>>>>>>>>> That is more power than we need here, but it provided me the 
>>>>>>>>>>> inspiration for a potential solution to the factory problem. Back 
>>>>>>>>>>> to swift…
>>>>>>>>>>> 
>>>>>>>>>>> The idea here is to give each interested subclass a chance to say 
>>>>>>>>>>> “I've got this!”. The factory init runs through each of the 
>>>>>>>>>>> subclasses’ overrides until it finds one that doesn’t return nil. 
>>>>>>>>>>> New subclasses can be added and they will be given a chance as well 
>>>>>>>>>>> (without modifying the base class). The first subclass to 
>>>>>>>>>>> successfully init wins. (only subclasses which override the factory 
>>>>>>>>>>> init would be considered)
>>>>>>>>>>> 
>>>>>>>>>>> class AbstractBase {
>>>>>>>>>>>     public factory init?(type: InformationToSwitchOn){
>>>>>>>>>>>         //I like having an explicit call, so that the traditional 
>>>>>>>>>>> (non-distributed) factory is possible as well
>>>>>>>>>>>         return factory.init(type) //We could also call this 
>>>>>>>>>>> “subclass.init(type)” to mirror super
>>>>>>>>>>>     }
>>>>>>>>>>> }
>>>>>>>>>>> class ConcreteImplementation : AbstractBase {
>>>>>>>>>>>     public factory override init?(type: InformationToSwitchOn){
>>>>>>>>>>>         guard type == compatibleWithThisType else {return nil} //If 
>>>>>>>>>>> info doesn’t work for us, we return nil, and the next class gets a 
>>>>>>>>>>> shot
>>>>>>>>>>>     //Init concrete type here
>>>>>>>>>>>     }
>>>>>>>>>>> }
>>>>>>>>>>> 
>>>>>>>>>>> The main issue which still needs to be solved is that the order 
>>>>>>>>>>> they get called sometimes really matters (this was solved by a well 
>>>>>>>>>>> defined ordering + IDE features in the language mentioned above). 
>>>>>>>>>>> For the most part, as long as subclasses are called before their 
>>>>>>>>>>> superclasses (or there is a some method for cascading), it works. 
>>>>>>>>>>> There are still times where you want to define a specific ordering 
>>>>>>>>>>> though (e.g. a new subclass wants to get called before an existing 
>>>>>>>>>>> subclasses to override some of it’s use cases).
>>>>>>>>>>> I see a few options (and I would love to hear more):
>>>>>>>>>>> - subclasses define a numeric precedence (similar to operators 
>>>>>>>>>>> now). This is probably the most effective stop-gap solution, but is 
>>>>>>>>>>> not elegant.
>>>>>>>>>>> - subclasses do whatever we change operator precedence to do in the 
>>>>>>>>>>> future
>>>>>>>>>>> - optionally allow subclasses to name another specific subclass 
>>>>>>>>>>> that they are before/after
>>>>>>>>>>> - allow subclasses to declare that they would like to be earlier or 
>>>>>>>>>>> later (or that they don’t care) in the calling list. subclasses 
>>>>>>>>>>> defined outside of the module where the base class was defined 
>>>>>>>>>>> would be placed more extremely early/late. Exact order is 
>>>>>>>>>>> undefined, but rough ordering is possible.
>>>>>>>>>>> - return (to the superclass) an array of all subclasses which 
>>>>>>>>>>> successfully inited. It can then select which one it wants and 
>>>>>>>>>>> return it. This seems overly inefficient to me, since you are 
>>>>>>>>>>> initializing a bunch of unused objects.
>>>>>>>>>>> - <Your idea here>
>>>>>>>>>>> 
>>>>>>>>>>> The end result is that you can extend factories of both classes and 
>>>>>>>>>>> protocols without access to the original source code.  
>>>>>>>>>>> 
>>>>>>>>>>> I also don’t think that the base should always need to be abstract. 
>>>>>>>>>>> Factory inits should allow returning subclasses as a way of 
>>>>>>>>>>> replacing themselves with a subclass, and returning nil if they are 
>>>>>>>>>>> failable, but if there is no return (or return self), it can create 
>>>>>>>>>>> an instance of itself. This way, it provides a customization point 
>>>>>>>>>>> where subclasses can handle special cases, but the class itself 
>>>>>>>>>>> provides an obvious default (i.e. a much less messy form of class 
>>>>>>>>>>> cluster).
>>>>>>>>>>> 
>>>>>>>>>>> class Base {
>>>>>>>>>>>     public factory init(type: InformationToSwitchOn){
>>>>>>>>>>>     if let subclass = factory.init(type){
>>>>>>>>>>>         return subclass
>>>>>>>>>>>     }
>>>>>>>>>>>     return self.init()//If subclasses didn’t work, initialize 
>>>>>>>>>>> ourselves
>>>>>>>>>>>     }
>>>>>>>>>>> }
>>>>>>>>>>> 
>>>>>>>>>>> Thoughts?  Too crazy to consider?
>>>>>>>>>>> 
>>>>>>>>>>> Thanks,
>>>>>>>>>>> Jon
>>>>>>>>>>> 
>>>>>>>>>>> On Feb 8, 2016, at 11:26 AM, Charles Srstka <cocoadev at 
>>>>>>>>>>> charlessoft.com 
>>>>>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>> wrote:
>>>>>>>>>>> 
>>>>>>>>>>> >> On Dec 17, 2015, at 3:41 PM, Riley Testut via swift-evolution 
>>>>>>>>>>> >> <swift-evolution at swift.org 
>>>>>>>>>>> >> <https://lists.swift.org/mailman/listinfo/swift-evolution>> 
>>>>>>>>>>> >> 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 <phausler at 
>>>>>>>>>>> >>> apple.com 
>>>>>>>>>>> >>> <https://lists.swift.org/mailman/listinfo/swift-evolution>> 
>>>>>>>>>>> >>> 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 at 
>>>>>>>>>>> >>> architechies.com 
>>>>>>>>>>> >>> <https://lists.swift.org/mailman/listinfo/swift-evolution>> 
>>>>>>>>>>> >>> 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
>>>>>>>>>>> >> swift-evolution at swift.org 
>>>>>>>>>>> >> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>>>>>>> >> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>>>>>>>>> >> <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
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to