[swift-evolution] [Proposal] Factory Initializers

Pranshu Goyal pranshu.goyal at novanet.net
Sun Jun 4 10:07:15 CDT 2017


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*
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170604/9c01f3f4/attachment.html>


More information about the swift-evolution mailing list