[swift-evolution] [Proposal] Factory Initializers

Xiaodi Wu xiaodi.wu at gmail.com
Mon Jun 5 02:16:33 CDT 2017


I hope so! We'll have to wait a bit for the core team to outline Swift 5
priorities.


On Mon, Jun 5, 2017 at 00:24 Pranshu Goyal <pranshu.goyal at novanet.net>
wrote:

> Any hopes for it in future?
>
> On 4 June 2017 at 20:40, Xiaodi Wu <xiaodi.wu at gmail.com> wrote:
>
>> No.
>>
>>
>>
>> On Sun, Jun 4, 2017 at 10:07 Pranshu Goyal via swift-evolution <
>> swift-evolution at swift.org> wrote:
>>
>>> Is this proposal in the pipeline for Swift 4?
>>>
>>> On 1 April 2017 at 12:03, Adrian Zubarev via swift-evolution <
>>> swift-evolution at swift.org> wrote:
>>>
>>>> First, you should fix the indent in the code samples. Second, remove
>>>> any access modifier from inside a protocol. Third, we don’t support default
>>>> implementations directly inside protocols yet, so that’s a not valid
>>>> example.
>>>>
>>>> Now my personal concerns. As far as I can tell XIB files in an iOS
>>>> Project are meant for UIViewControllers in first place, but it’s a common
>>>> case that they are also used to create reusable UIViews. The downside of
>>>> that abusage is view hierarchy clustering. Most developer creating a view
>>>> of Self in Self, which smells to me like really bad code.
>>>>
>>>> MyCustomView // This view is useless
>>>>    + MyCustomView
>>>>        + CustomSubview1
>>>>    + CustomSubview1 // This is probably a dead IBOutlet
>>>>
>>>> In fact Xcode does not use the initializer from NSCoding to show a
>>>> live rendered view inside interface builder, instead it will call a UIViews
>>>> designated initializer init(frame:). That results that a lot of the
>>>> developer write similar code like in the following snippet:
>>>>
>>>> // This pattern results in a similar view cluster like mentioned above
>>>>
>>>> class MyCustomView : UIView {
>>>>     override init(frame: CGRect) {
>>>>         let view = loadSomehowFromNib()
>>>>         self.addSubview(view)
>>>>     }
>>>> }
>>>>
>>>> To solve this problem we’d need some functionality of factory
>>>> initializers. I believe as proposed the factory initializer won’t solve
>>>> that problem, because everything would be still restricted to a special
>>>> initializer annotated with factory.
>>>>
>>>> Personally I would want to write something like this instead.
>>>>
>>>> class MyCustomView : UIView {
>>>>
>>>>     override init(frame: CGRect) {
>>>>
>>>>         // Instantiating from a Nib file will call `init(coder:​)` on MyCustomView
>>>>         self = loadSomehowFromNib() // assuming () -> MyCustomView
>>>>
>>>>         //
>>>>         self.frame = frame
>>>>     }
>>>> }
>>>>
>>>> This should resolve the clustering issue by assigning the returned
>>>> instance from the function to self and create a correct view hierarchy.
>>>>
>>>> + MyCustomView
>>>>        + CustomSubview1
>>>>
>>>>
>>>>
>>>> --
>>>> Adrian Zubarev
>>>> Sent with Airmail
>>>>
>>>> Am 17. März 2017 um 17:26:29, Riley Testut via swift-evolution (
>>>> swift-evolution at swift.org) schrieb:
>>>>
>>>> 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
>>>>
>>>>
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> swift-evolution at swift.org
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>
>>>>
>>>
>>>
>>> --
>>> *Pranshu Goyal*
>>> *iOS Developer*
>>> *tlkn*
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>
>>
>
>
> --
> *Pranshu Goyal*
> *iOS Developer*
> *tlkn*
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170605/690dad95/attachment.html>


More information about the swift-evolution mailing list