[Pitch] CRTP in Swift


(Adrian Zubarev) #1

First of all, writing CRTP is already allowed in Swift, however it doesn’t work at all.

For example one would assume that the output of the following code sample might look like this 1 2 3 4:

print(1)

class Template<T> {}

class RealThing : Template<RealThing> {
    override init() { print(2) }
    func foo() { print(3) }
}

let instance = RealThing()
instance.foo()

print(4)
However the result is only 1 and your application will simply stuck at that point without crashing or throwing any bad runtime error.

https://bugs.swift.org/browse/SR–2549

I discovered an API in UIKit which uses that pattern, obviously it’s written in Objective-C but it is imported in Swift and it actually works, because it’s not pure swift.

// Generic superclass
open class NSLayoutAnchor<AnchorType : AnyObject> : NSObject { ... }

// Non-generic subclasses with the `Sub : Super<Sub>` pattern
open class NSLayoutXAxisAnchor : NSLayoutAnchor<NSLayoutXAxisAnchor> {}
open class NSLayoutYAxisAnchor : NSLayoutAnchor<NSLayoutYAxisAnchor> {}
open class NSLayoutDimension : NSLayoutAnchor<NSLayoutDimension> { ... }
My questions are:

Will we ever allow this in Swift?
Does CRTP bring any technical improvement to Swifts generic system?
Is it something for Swift 4 to consider?
Does it need a proposal or should we only see it as a bug?

···

--
Adrian Zubarev
Sent with Airmail


(David Sweeris) #2

For those who might not know what the acronym stands for: https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern

I can’t think of any non-technical reasons to prohibit it, so to me, this not being supported is either a bug or a technical limitation of type system. Actually, I’d say the specific behavior you’re describing is a bug regardless, since the compiler should throw an error if it comes across code that it can see will get the type system into an infinite loop.

- Dave Sweeris

···

On Feb 23, 2017, at 10:54 AM, Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:

First of all, writing CRTP is already allowed in Swift, however it doesn’t work at all.

For example one would assume that the output of the following code sample might look like this 1 2 3 4:

print(1)

class Template<T> {}

class RealThing : Template<RealThing> {
    override init() { print(2) }
    func foo() { print(3) }
}

let instance = RealThing()
instance.foo()

print(4)
However the result is only 1 and your application will simply stuck at that point without crashing or throwing any bad runtime error.

https://bugs.swift.org/browse/SR–2549 <https://bugs.swift.org/browse/SR-2549>
I discovered an API in UIKit which uses that pattern, obviously it’s written in Objective-C but it is imported in Swift and it actually works, because it’s not pure swift.

// Generic superclass
open class NSLayoutAnchor<AnchorType : AnyObject> : NSObject { ... }

// Non-generic subclasses with the `Sub : Super<Sub>` pattern
open class NSLayoutXAxisAnchor : NSLayoutAnchor<NSLayoutXAxisAnchor> {}
open class NSLayoutYAxisAnchor : NSLayoutAnchor<NSLayoutYAxisAnchor> {}
open class NSLayoutDimension : NSLayoutAnchor<NSLayoutDimension> { ... }
My questions are:

Will we ever allow this in Swift?
Does CRTP bring any technical improvement to Swifts generic system?
Is it something for Swift 4 to consider?
Does it need a proposal or should we only see it as a bug?