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]> 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