One concept to consider here is that the initializers that are factories may or 
may not replace self;

Take for example NSArray (inspired from the objective-c implementation but 
written in swift, but note this is not the only use case)

public init(objects: UnsafePointer<AnyObject>!, count cnt: Int) {
    if count == 0 && type(of: self) == NSArray.self {
        // specialized NSArray that does not contain any objects; it is a 
singleton so we dont need to allocate at all
        return __NSArray0.zeroElementSingleton
    } else if count == 1 type(of: self) == NSArray.self {
        // The single object version is more effecient since it does not need 
to indirect to a buffer
        return __NSArray1(objects.pointee)
    } else if type(of: self) == NSArray.self {
        return CFArrayCreate(kCFAllocatorSystemDefault, 
UnsafeMutablePointer<UnsafeRawPointer?>(objects), cnt, &kCFTypeArrayCallBacks)
    } else {
        _storage.reserveCapacity(cnt)
        for idx in 0..<cnt {
            _storage.append(objects[idx])
        }
    }
}

This would mean that in the cases of 0 elements when NSArray itself is created 
we can avoid allocating, when the count is 1 and it is an NSArray itself we can 
emit a more effecient storage, then when the type is immuatable we can fall to 
CF, and finally in the abstract case we can store elements in a buffer directly.

> On Mar 21, 2017, at 4:28 PM, Charlie Monroe via swift-evolution 
> <[email protected]> wrote:
> 
> I believe that this proposal is trying to solve something that can be solved 
> by allowing assignment to self within convenience initializers. 
> 
> Unfortunately, even convenience initializers are allocating which makes it 
> harder to achieve with backward compatibility - though I'm not entirely sure 
> what would be the consequences of turning them into non-allocating.
> 
> If it's not possible due to implementational details, I'd suggest to rather 
> introduce a @nonallocating (or similar) annotation (keyword?) that can be 
> placed on init methods and it would then require for self to be assigned 
> during the initialization as long as the assigned value is subtype of the 
> receiver:
> 
> @nonallocating init(x: Int) {
>       if x < 0 {
>               self = NegativeMe(x: x)
>       } else {
>               self = PositiveMe(x: x)
>       }
> }
> 
> Which is pretty much what the proposal is suggesting, but removes the 
> "factory" keyword which may be a bit misleading or narrowly named.
> 
> 
>> On Mar 21, 2017, at 4:49 PM, David Rönnqvist via swift-evolution 
>> <[email protected] <mailto:[email protected]>> wrote:
>> 
>> Forgive me if that has already been discussed in the email threads prior to 
>> the proposal, but what I’m missing from this proposal is a discussion of the 
>> problems factory initializers solve (other than the examples at the end) and 
>> an explanation of why factory initializers are the right solution to 
>> that/those problems in Swift.
>> 
>> I acknowledge that it’s a common pattern in many languages, but don’t find 
>> it a very strong argument as to why it should be built into the language. 
>>  
>> Regards,
>> David
>> 
>> 
>>> On 17 Mar 2017, at 17:26, Riley Testut via swift-evolution 
>>> <[email protected] <mailto:[email protected]>> 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
>>>  
>>> <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 <[email protected] 
>>> <mailto:[email protected]>> 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 
>>>>> <[email protected] <mailto:[email protected]>> 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 
>>>>>> <[email protected] <mailto:[email protected]>> 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 <[email protected] 
>>>>>>> <mailto:[email protected]>> 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 <[email protected] 
>>>>>>> <mailto:[email protected]>> 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
>>>>>> [email protected] <mailto:[email protected]>
>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>> 
>>>>> _______________________________________________
>>>>> swift-evolution mailing list
>>>>> [email protected] <mailto:[email protected]>
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>> _______________________________________________
>>> swift-evolution mailing list
>>> [email protected] <mailto:[email protected]>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> 
>> _______________________________________________
>> swift-evolution mailing list
>> [email protected] <mailto:[email protected]>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to