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
