[Proposal] Factory Initializers

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@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@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

+1; this is a known-needed, missing feature.

-Dave

···

On Dec 17, 2015, at 1:41 PM, Riley Testut via swift-evolution <swift-evolution@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@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@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!

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 {

}

I’m confused, isn’t this already handled by “convenience” initializers?

What we lack now is the ability to use the AbstractBase(42) syntax the produce something with a static type of ConcreteImplementation. This is something expressible in Objective-C, and something that Swift can currently import into Objective-C, but that you can’t write directly in Swift code right now.

The approach that I would suggest is a simple extension of the grammar, to allow "-> T” on a convenience initializer. In this case, you could write:

class AbstractBase {
   convenience init(type: InformationToSwitchOn) -> ConcreteImplementation {
       return ConcreteImplementation(type)
   }

and then "AbstractBase(stuff)” would produce a value with the static type of ConcreteImplementation. This syntax is already produced by the AST printer for imported ObjC stuff, so we have much of the mechanics for this already in the compiler. It would be great to see someone push this forward!

-Chris

···

On Dec 17, 2015, at 1:41 PM, Riley Testut via swift-evolution <swift-evolution@swift.org> wrote:

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@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@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@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

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:

Thanks for working on this!

# 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.

For the record, the Swift compiler and programming model actually already has factory initializers, but one can only get to them by writing a factory method in Objective-C that then gets imported as a factory initializer into Swift. For example:

  @interface ABCFoo : NSObject
  +(nonnull ABCFoo *)fooWithString:(nonnull NSString *)string;
  @end

comes in as a factory initializer (using your proposed syntax):

  factory init(string: String)

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 {

}

FWIW, there’s a historical syntax here of

  public init(type: InformationToSwitchOn) -> AbstractBase

I’m not attached to the “->” syntax at all, but there were two reasons for using it for factory initializers:

  1) It more strongly indicates the “function” nature of this initializer, because you’re expected to return a “self” rather than initializing the “self” you’ve been given, which is very different from all other initializers. “Factory” also says that if you know what factory initializers are, but “->” is more firmly embedded in the language semantics to mean “you should return one of these”.

  2) It lets you distinguish between factory initializers that return “Self” (i.e., the type used to perform the initialization) and those that return some concrete upper bound (like your example). The distinction affects inheritance of initializers and, by extension, whether the initializer can satisfy an initializer requirement in a protocol. For example, in your example above, I would expect us to reject

    ConcreteImplementation(type: InformationToSwiftOn())

  because we have named “ConcreteImplementation” but the factory initializer is only guaranteed to provide an “AbstractBase”. If instead one had:

    public init(type: InformationToSwiftOn) -> Self { … }

  then

    ConcreteImplementation(type: InformationToSwiftOn())

  is well-formed and produces a ConcreteImplementation while

    AbstractBase(type: InformationToSwiftOn())

  is also well-formed and produces an AbstractBase. In other words, the factory initializer written “-> Self” is guaranteed to be inherited. Whether the others are inherited is more complicated.

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.

At least some of these cases would better be addressed by protocol initializers, below, because there might be no reason at all for the OS-appopriate “subclasses” to actually share a superclass (nor should they have to be classes!).

## 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.

Seems plausible.

  - Doug

···

On Dec 17, 2015, at 1:41 PM, Riley Testut via swift-evolution <swift-evolution@swift.org> wrote:

Strong +1 on this, particularly on the part about protocol initializers. This would bring together some of the best aspects of both Objective-C class clusters and Swift protocol-oriented programming and would be a huge benefit to application developers.

Charles

···

On Dec 17, 2015, at 3:41 PM, Riley Testut via swift-evolution <swift-evolution@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@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@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@swift.org
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

···

On Dec 17, 2015, at 3:41 PM, Riley Testut via swift-evolution <swift-evolution@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@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@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@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

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@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@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@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@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

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 {

}

I’m confused, isn’t this already handled by “convenience” initializers?

That first part of the post is handled by the convenience initializer syntax you suggest. Your suggestion doesn't address the idea of protocol initializers further down though. That is very interesting as well.

protocol P {}
struct S: P {}
extension P {
  factory init(type: InformationToSwitchOn) {
    return S()
  }
}

let p = P(type: informationToSwitchOn)

···

Sent from my iPad

On Dec 17, 2015, at 6:25 PM, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

On Dec 17, 2015, at 1:41 PM, Riley Testut via swift-evolution <swift-evolution@swift.org> wrote:

What we lack now is the ability to use the AbstractBase(42) syntax the produce something with a static type of ConcreteImplementation. This is something expressible in Objective-C, and something that Swift can currently import into Objective-C, but that you can’t write directly in Swift code right now.

The approach that I would suggest is a simple extension of the grammar, to allow "-> T” on a convenience initializer. In this case, you could write:

class AbstractBase {
  convenience init(type: InformationToSwitchOn) -> ConcreteImplementation {
      return ConcreteImplementationr(type)
  }

and then "AbstractBase(stuff)” would produce a value with the static type of ConcreteImplementation. This syntax is already produced by the AST printer for imported ObjC stuff, so we have much of the mechanics for this already in the compiler. It would be great to see someone push this forward!

-Chris

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@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@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@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

The reason for the additional “factory” keyword would be to differentiate it from other initializers because it actually “returned" a value. For the record, I am entirely in support of modifying convenience initializers to return instances directly; I assumed (incorrectly it seems!) that the ability to return directly from an initializer was intentionally left out, for whatever reason. I agree using the convenience initializer syntax with an explicit return type would be a better approach, and would be more in-line with what you can do with initializers in Objective-C :-)

If this is already implemented in the compiler, I would love to certainly push this idea forward! I genuinely believe this could add great value to the language, without changing the fundamentals too much.

···

On Dec 17, 2015, at 6:25 PM, Chris Lattner <clattner@apple.com> wrote:

On Dec 17, 2015, at 1:41 PM, Riley Testut via swift-evolution <swift-evolution@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 {

}

I’m confused, isn’t this already handled by “convenience” initializers?

What we lack now is the ability to use the AbstractBase(42) syntax the produce something with a static type of ConcreteImplementation. This is something expressible in Objective-C, and something that Swift can currently import into Objective-C, but that you can’t write directly in Swift code right now.

The approach that I would suggest is a simple extension of the grammar, to allow "-> T” on a convenience initializer. In this case, you could write:

class AbstractBase {
  convenience init(type: InformationToSwitchOn) -> ConcreteImplementation {
      return ConcreteImplementation(type)
  }

and then "AbstractBase(stuff)” would produce a value with the static type of ConcreteImplementation. This syntax is already produced by the AST printer for imported ObjC stuff, so we have much of the mechanics for this already in the compiler. It would be great to see someone push this forward!

-Chris

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@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@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@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

Now I'm confused: I thought the idea should enable class clusters, i.e. allowing AbstractBaseClass(42) to return something with the *dynamic* type of ConcreteImplementation but still the static type of AbstractBaseClass.
Otherwise I would just call ConcreteImplementation(42) if I wanted something of that static type.

-Thorsten

···

Am 18.12.2015 um 01:25 schrieb Chris Lattner via swift-evolution <swift-evolution@swift.org>:

On Dec 17, 2015, at 1:41 PM, Riley Testut via swift-evolution <swift-evolution@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 {

}

I’m confused, isn’t this already handled by “convenience” initializers?

What we lack now is the ability to use the AbstractBase(42) syntax the produce something with a static type of ConcreteImplementation. This is something expressible in Objective-C, and something that Swift can currently import into Objective-C, but that you can’t write directly in Swift code right now.

The approach that I would suggest is a simple extension of the grammar, to allow "-> T” on a convenience initializer. In this case, you could write:

class AbstractBase {
  convenience init(type: InformationToSwitchOn) -> ConcreteImplementation {
      return ConcreteImplementation(type)
  }

and then "AbstractBase(stuff)” would produce a value with the static type of ConcreteImplementation. This syntax is already produced by the AST printer for imported ObjC stuff, so we have much of the mechanics for this already in the compiler. It would be great to see someone push this forward!

-Chris

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@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@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@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

1 Like

Glad to see there's definitely some interest in this community then! I would love to start writing up a final proposal to submit to the Swift-Evolution repo, but I think that last piece of information needed would be the actual method of initialization, specifically should we allow for returning instances from convenience initializers, or should we simply assign to self?

Personally, I think returning from the initializer makes the most sense, especially because "self" in a protocol extension seems ambiguous. However, I'm not that much in favor that I couldn't be convinced to simply assign to self, because that already has some low level support in the language. Anyone have strong thoughts one way or another?

···

On Dec 22, 2015, at 1:00 PM, Charles Srstka <cocoadev@charlessoft.com> wrote:

Strong +1 on this, particularly on the part about protocol initializers. This would bring together some of the best aspects of both Objective-C class clusters and Swift protocol-oriented programming and would be a huge benefit to application developers.

Charles

On Dec 17, 2015, at 3:41 PM, Riley Testut via swift-evolution <swift-evolution@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@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@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@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Hey all!

Very sorry, restored my MacBook at the beginning of the calendar year, and forgot to re-subscribe to Swift-Evolution 😄. Once I realized this, I decided to hold off on pushing this forward till after Swift 2.2, and now that it's been released, I'd love to make moves on this!

So, is there still an interest in the proposal? If so, I'll write up a new proposal with everyone's feedback, and then post it here for more discussion. I think this would very valuable (and would certainly help a bunch in my current app), but want to see where everyone stands!

Riley Testut

···

On Feb 8, 2016, at 11:26 AM, Charles Srstka <cocoadev@charlessoft.com> wrote:

On Dec 17, 2015, at 3:41 PM, Riley Testut via swift-evolution <swift-evolution@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@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@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@swift.org
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

Howdy,
  Yes, I would like a feature like this. I’m working on a number of apps where I have a number of concrete types which conform to a protocol. Deserializing means picking one, and I’d love to be able to declare a protocol-scoped method which can pick between different subclasses. In some cases, I implement these as enums, but that unfortunately puts together a lot of code that I’d rather have apart.

My question is why bother writing “init” if I’ve already written “factory”? It isn’t really an initializing anything, it’s actually delegating. It really is just a static method, but a commonly-named and syntactically convenient way for someone to not know -or not need to know- that they are actually creating a subtype.

At that point, given that many of these are protocol-centric, what I want from a language standpoint is a way to define a protocol-scoped method. In contrast to a static method, which can only be called from a concrete type which conforms to the protocol, in initializing the correct sub-type, we do not yet know the correct sub-type.

For instance, consider a presentation app which contains an array of user “entries”, which can be text, images, whatever.

  protocol PresentationEntry {
  }
  extension PresentationEntry
    protocol func new(json:[String:Any])throws-> PresentationEntry {
      //…
      if whatever {
        return TextEntry(…
      else {
        return ImageEntry(...
    }
  }
  struct TextEntry : PresentationEntry {
  }
  struct ImageEntry : PresentationEntry {
  }

  class Presentation {
    var entries:[PresentationEntry]
    init(json:[String:Any])throws {
      //…
      self.entries = entriesJson.flatMap(){ (json)-> PresentationEntry? in
        return try? PresentationEntry.new(json:json)
      }
    
Right now, I think I’m stuck tacking the creation method on somewhere, like as an instance method on the Presentation type, as a global function, or creating a type to do nothing but be the factory.

At that point, the question revolves around extensibility. What if a sub-class adds another conforming type of concrete subclass? That’s what protocols and classes are for, after all! How do I modify the protocol’s protocol-scoped method to be overridden? Using custom factory types,

  i.e.
  protocol PresentationEntryFactory : class {
    weak var presentationFactory: PresentationFactory? { get set }
    func new(json:[String:Any], factory:PresentationEntryFactory)throws->PresentationEntry {
      ...
    }
  }
  class GenericPresentationEntryFactory : PresentationEntryFactory {
    func new(json:[String:Any])throws->PresentationEntry {
      if whatever {
        return TextEntry(json:…, factory:Self)
      else {
        return ImageEntry(json:…, factory:Self)
    }
    ...
  }

I don’t have that problem. I just create my own factory type, using exactly the same interface:

  struct SongEntry : PresentationEntry {
    ...
  }
  class SongCapablePresentationEntryFactory : PresentationEntryFactory {
    func new(json:[String:Any])throw->PresentationEntry {
      if whatever {
        return TextEntry(json:…, factory:self)
      else if whenever {
        return ImageEntry(json:…, factory:self)
      else {
        return SongEntry(json:…, factory:self)
    }
  }

And now Presentation just gets its “entryFactory” from its factory and creates the entries.

Or perhaps the PresentationFactory creates the entries before it even creates the presentation and there never was a init(json:… method on the Presentation in the first place. But I get that one goal is to avoid the need to create all these additional factory classes. A lot of developers would prefer to simply use an init( and never write them out.

So that’s a ‘general’ way to solve the problem now. I’m not 100% sure that we have to have extensibility of these factory or protocol-scoped methods to proceed, but it would be nice to see what could happen with extensiblility with some more minds checking on this list. Maybe a type “registration” method? We could create a “factory register” keyword which tells the compiler to place the given type in a special run-time accessible location including a reference to the concrete type and a validation function. Unfortunately, the validation function may need to be custom not only by protocol, but also by starting data. Consider a type which can be initialized from NSCoder, JSON, NSManagedObject and also from a CKRecord (I have that in several apps). How many factories do we have for a type? How do we distinguish them? Argument labels and types? How many validation methods need to be specified? Obviously, it would be nice to have the compiler check for our errors in that.

Not using a specific “factory” keyword method, but adding “protocol”-scoped stored properties allows me to specify a different factory closure:

  extension PresentationEntry {
    protocol var jsonEntryFactory:(json:[String:Any])throws->Self

Then my second app, which supports more Entry types, but embeds the original module, could simply

    PresentationEntry.jsonEntryFactory = { (…)->PresentationEntry in
      if whatever {
        return TextEntry(json:…, factory:self)
      else if whenever {
        return ImageEntry(json:…, factory:self)
      else {
        return SongEntry(json:…, factory:self)
    
But it doesn’t answer the question of “when” do we set this value. Do I just do it “early”? and hope I don’t end up writing yet another inheriting module?

CoreImage really wants to work that way, with the init(name:… pattern. On the other hand, I can’t tell you whether the CoreImage team is happy with that API, but I can tell you I’m not. I want @availability attributes on concrete types, so I know the type doesn’t work before I build an entire app built on using the variable blur filter and then realize that I misread the docs. So, how would @availability play into factory type registrations?

But, I feel like this need kind of starts to spider out into a ton of considerations to really get us what we can use.

+1 for factory keyword
-1 for still needing to type “init”
+1 for protocol-scoped members without needing a conforming concrete type
-1 for consideration of extensibility of factories.
+1 for directly representing the as-designed initialization patterns of several popular modules
-1 for such long tendrils

-Ben Spratling

···

On Nov 17, 2016, at 4:23 PM, Charles Srstka via swift-evolution <swift-evolution@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@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@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@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@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

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@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@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@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@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@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Now I'm confused: I thought the idea should enable class clusters, i.e. allowing AbstractBaseClass(42) to return something with the *dynamic* type of ConcreteImplementation but still the static type of AbstractBaseClass.
Otherwise I would just call ConcreteImplementation(42) if I wanted something of that static type.

Got it. If that is the case, then yes, something like a “factory init” makes sense to me. It is unfortunate that such a thing would make the swift initializer model even MORE complex :-) but it is probably still the right way to go.

-Chris

···

On Dec 18, 2015, at 8:15 AM, Thorsten Seitz <tseitz42@icloud.com> wrote:

-Thorsten

Am 18.12.2015 um 01:25 schrieb Chris Lattner via swift-evolution <swift-evolution@swift.org>:

On Dec 17, 2015, at 1:41 PM, Riley Testut via swift-evolution <swift-evolution@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 {

}

I’m confused, isn’t this already handled by “convenience” initializers?

What we lack now is the ability to use the AbstractBase(42) syntax the produce something with a static type of ConcreteImplementation. This is something expressible in Objective-C, and something that Swift can currently import into Objective-C, but that you can’t write directly in Swift code right now.

The approach that I would suggest is a simple extension of the grammar, to allow "-> T” on a convenience initializer. In this case, you could write:

class AbstractBase {
convenience init(type: InformationToSwitchOn) -> ConcreteImplementation {
     return ConcreteImplementation(type)
}

and then "AbstractBase(stuff)” would produce a value with the static type of ConcreteImplementation. This syntax is already produced by the AST printer for imported ObjC stuff, so we have much of the mechanics for this already in the compiler. It would be great to see someone push this forward!

-Chris

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@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@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@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

In the implementation model, if not the language model, convenience inits today pretty much already are factory initializers, since the ABI allows for a different `self` object to be returned as long as it's a subclass of the current type, much like a factory method. Instead of adding another wrinkle to the initializer model, we could embrace this, and allow convenience inits to reassign `self` as in ObjC. This would also bring more consistency between struct and class initializers, since struct initializers are already able to reassign `self` as well. We have to interop with the [[T alloc] init] model for ObjC classes, so we'd have to deallocate a wasted empty object if a convenience initializer for an @objc class changes self, but the ABI for pure Swift convenience initializers could be made to be callee-allocating to avoid that performance problem.

-Joe

···

On Dec 18, 2015, at 12:39 PM, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

On Dec 18, 2015, at 8:15 AM, Thorsten Seitz <tseitz42@icloud.com> wrote:

Now I'm confused: I thought the idea should enable class clusters, i.e. allowing AbstractBaseClass(42) to return something with the *dynamic* type of ConcreteImplementation but still the static type of AbstractBaseClass.
Otherwise I would just call ConcreteImplementation(42) if I wanted something of that static type.

Got it. If that is the case, then yes, something like a “factory init” makes sense to me. It is unfortunate that such a thing would make the swift initializer model even MORE complex :slight_smile: but it is probably still the right way to go.

I’m not opposed to assigning to self directly in convenience initializers (especially if there is already support for it in the ABI). My only concern would be that it feels less “natural” to do so than to simply return a value from the initializer. That being said, I think that’s a very negligible disadvantage (if even that), and if assigning to self is the easiest way to pull this off, I’m all for it.

However, should we keep convenience initializers as the only way to assign self directly, and required initializers keep the same behavior as they do today? And then would it make sense to disable the assignment to self in struct required initializers to keep things consistent? Don’t have a strong preference for any of these, but I do think they’re worth discussing.

···

On Dec 18, 2015, at 3:06 PM, Joe Groff via swift-evolution <swift-evolution@swift.org> wrote:

On Dec 18, 2015, at 12:39 PM, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

On Dec 18, 2015, at 8:15 AM, Thorsten Seitz <tseitz42@icloud.com> wrote:

Now I'm confused: I thought the idea should enable class clusters, i.e. allowing AbstractBaseClass(42) to return something with the *dynamic* type of ConcreteImplementation but still the static type of AbstractBaseClass.
Otherwise I would just call ConcreteImplementation(42) if I wanted something of that static type.

Got it. If that is the case, then yes, something like a “factory init” makes sense to me. It is unfortunate that such a thing would make the swift initializer model even MORE complex :-) but it is probably still the right way to go.

In the implementation model, if not the language model, convenience inits today pretty much already are factory initializers, since the ABI allows for a different `self` object to be returned as long as it's a subclass of the current type, much like a factory method. Instead of adding another wrinkle to the initializer model, we could embrace this, and allow convenience inits to reassign `self` as in ObjC. This would also bring more consistency between struct and class initializers, since struct initializers are already able to reassign `self` as well. We have to interop with the [[T alloc] init] model for ObjC classes, so we'd have to deallocate a wasted empty object if a convenience initializer for an @objc class changes self, but the ABI for pure Swift convenience initializers could be made to be callee-allocating to avoid that performance problem.

-Joe
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

Assigning to self was always a bit weird. I think returning an instance makes more sense intuitively. It’s also, as you say, unclear exactly what “self” even means in the context of a protocol.

Probably the way I’d do it would be to have the method declared “factory init” and be required to return an object.

Charles

···

On Dec 23, 2015, at 11:09 PM, Riley Testut <rileytestut@gmail.com> wrote:

Glad to see there's definitely some interest in this community then! I would love to start writing up a final proposal to submit to the Swift-Evolution repo, but I think that last piece of information needed would be the actual method of initialization, specifically should we allow for returning instances from convenience initializers, or should we simply assign to self?

Personally, I think returning from the initializer makes the most sense, especially because "self" in a protocol extension seems ambiguous. However, I'm not that much in favor that I couldn't be convinced to simply assign to self, because that already has some low level support in the language. Anyone have strong thoughts one way or another?

Very strong +1 for factory initializers on both classes and protocols.

Charles

···

On Mar 22, 2016, at 1:16 AM, Riley Testut <rileytestut@gmail.com> wrote:

Hey all!

Very sorry, restored my MacBook at the beginning of the calendar year, and forgot to re-subscribe to Swift-Evolution :smile:. Once I realized this, I decided to hold off on pushing this forward till after Swift 2.2, and now that it's been released, I'd love to make moves on this!

So, is there still an interest in the proposal? If so, I'll write up a new proposal with everyone's feedback, and then post it here for more discussion. I think this would very valuable (and would certainly help a bunch in my current app), but want to see where everyone stands!

Riley Testut

On Feb 8, 2016, at 11:26 AM, Charles Srstka <cocoadev@charlessoft.com> wrote:

On Dec 17, 2015, at 3:41 PM, Riley Testut via swift-evolution <swift-evolution@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@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@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@swift.org
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

Definitely a +1 here on interest for this proposal, have run into this
several times.

···

On Tue, Mar 22, 2016 at 5:16 PM, Riley Testut via swift-evolution < swift-evolution@swift.org> wrote:

Hey all!

Very sorry, restored my MacBook at the beginning of the calendar year, and
forgot to re-subscribe to Swift-Evolution :smile:. Once I realized this, I
decided to hold off on pushing this forward till after Swift 2.2, and now
that it's been released, I'd love to make moves on this!

So, is there still an interest in the proposal? If so, I'll write up a new
proposal with everyone's feedback, and then post it here for more
discussion. I think this would very valuable (and would certainly help a
bunch in my current app), but want to see where everyone stands!

Riley Testut

On Feb 8, 2016, at 11:26 AM, Charles Srstka <cocoadev@charlessoft.com> > wrote:

>> On Dec 17, 2015, at 3:41 PM, Riley Testut via swift-evolution < > swift-evolution@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@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@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@swift.org
>> 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
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution