[swift-evolution] [Proposal] Factory Initializers
Zach Waldowski
zach at waldowski.me
Fri Mar 17 13:15:34 CDT 2017
Big +1.
Two small nits/questions:
- What's the motivation behind using `return` rather than self-
assignment, like we currently have in inits for structs/enums and
protocol extensions? I didn't follow the original discussion in depth,
so excuse me if this has been hashed out before.
- Is the "factory" keyword truly necessary, or could it be implied by
"required" and using self-assignment in the init body?
Best,
Zachary Waldowski
zach at waldowski.me
On Fri, Mar 17, 2017, at 12:26 PM, Riley Testut via swift-evolution wrote:
>
>
> Hi again everyone!
>
> Now that Swift 4 Stage 2 proposals are being considered, I thought it
> might be time to revisit this proposal and see if it might align with
> the goals set forth for Swift 4.
>
> As a quick tl;dr, this proposal describes a new "factory initializer"
> that would allow you to return a value from an initializer. This would
> have several benefits, as mentioned in the proposal itself as well as
> throughout this mailing list. For convenience, here's a link to the
> proposal on GitHub:
> https://github.com/rileytestut/swift-evolution/blob/master/proposals/NNNN-factory-initializers.md
>
> Would love to hear any more comments on this proposal, and if we feel
> this is appropriate for considering for Swift 4 I'll happily re-open
> the pull request!
>
> Riley Testut
>
> On Nov 19, 2016, at 7:45 AM, arkadi daniyelian
> <arkdan at icloud.com> wrote:
>> i would appreciate this feature.
>>
>> For unexperienced developers, its often hard to recognize *when*
>> factory is a good fit to do the job, and how exactly approach the
>> implementation. I imagine having this feature built into the
>> language may help to choose and implement factory when its the right
>> thing to do.
>>
>>> On Nov 18, 2016, at 12:23 AM, Charles Srstka via swift-evolution <swift-
>>> evolution at swift.org> wrote:
>>>
>>> Is there any chance of reviving this? It seems to me that since this
>>> would require Swift initializers to be implemented internally in
>>> such a way that they can return a value (as Objective-C init methods
>>> do), it may affect ABI stability and thus may be germane to the
>>> current stage of Swift 4 development.
>>>
>>> Charles
>>>
>>>> On Dec 17, 2015, at 3:41 PM, Riley Testut via swift-evolution <swift-
>>>> evolution at swift.org> wrote:
>>>>
>>>> Recently, I proposed the idea of adding the ability to implement
>>>> the "class cluster" pattern from Cocoa (Touch) in Swift. However,
>>>> as we discussed it and came up with different approaches, it
>>>> evolved into a functionality that I believe is far more beneficial
>>>> to Swift, and subsequently should be the focus of its own proposal.
>>>> So here is the improved (pre-)proposal:
>>>>
>>>> # Factory Initializers
>>>>
>>>> The "factory" pattern is common in many languages, including Objective-
>>>> C. Essentially, instead of initializing a type directly, a method
>>>> is called that returns an instance of the appropriate type
>>>> determined by the input parameters. Functionally this works well,
>>>> but ultimately it forces the client of the API to remember to call
>>>> the factory method instead, rather than the type's initializer.
>>>> This might seem like a minor gripe, but given that we want Swift to
>>>> be as approachable as possible to new developers, I think we can do
>>>> better in this regard.
>>>>
>>>> Rather than have a separate factory method, I propose we build the
>>>> factory pattern right into Swift, by way of specialized “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>
>>>>> 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> 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
>>>
>>> _______________________________________________
>>> swift-evolution mailing list swift-evolution at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
> _________________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170317/bdde7e57/attachment.html>
More information about the swift-evolution
mailing list