When is the right time to push SE-0068?

Hi Swift community and all the great devs working on the Swift compiler. I'm wondering when it's finally time to push the implementation of SE-0068 forward?


There is a small but very useful pattern I'd like to implement on a base class type. However this pattern requires the missing feature and has no other way to workaround it (except writing the same boilerplate code over and over).

protocol Container : AnyObject {
  var coordinator: Coordinator<Self> { get }
}

class Base<T> where T : Container {
  unowned let interface: T

  init(interface: T) {
    self.interface = interface
  }
}

final class Coordinator<T> :
  Base<T> where T : Container {}

class BaseContainer : Container {
  private(set) lazy var coordinator = Coordinator<Self>(interface: self)
                                                  ^~~~
}

I re-read the rationale of the proposal and if I recall correctly someone said once that the core team decided differently then the stated in the rationale. If I'm not mistaken then there will be no Self on value types? (Please correct me if I'm wrong.) I personally would really miss it, but Self on classes is better then nothing.

3 Likes

The main issue here has been the poor representation of Self in the compiler. Effectively, dynamic Self ought to be treated more like a generic parameter in contexts where it's available, but it's currently treated as a special case in the few places it's supported, which is not a scalable model for generalizing where it can be used. We've made incremental progress in improving the model, but there's still a lot of work to do before this would be practical to implement.

3 Likes

Is this:

anyway important before ABI? By that I mean the things that are missing before the proposal can be implemented will be implemented before or after Swift 5 (not saying that the proposal will be implemented for Swift 5, even if I'd wish for it).

There shouldn't be any ABI impact.

1 Like

Swift 5.1
https://github.com/apple/swift/pull/22863

5 Likes

I know already for a couple month, but thank you nevertheless.

Yeah, I was thinking to have a ”conclusion” to this thread if someone searches for / stumbles upon this topic

2 Likes

The implementation has been merged and is available in the swift.org nightlies if you want to try it out.

2 Likes

I like SE-0068, but it seems there are still many limits.
Coordinator<Self> is still unsupported. Self can't work with generic. That means we can't write [Self] or Self?.

2 Likes

There are limitations that will have to be sorted out with time including Adrian’s example. You should be able to use [Self] as an argument type on a struct however:

struct A {

    var v = 99

    static func b(a: [Self]) {
        print("Hello, World! \(a)")
    }

    func a() {
        Self.b(a: [Self.init()])
    }
}

For anything else please file a Jira with example code.

2 Likes

With the nightly builds, the as? Self works great in classes, awesome!

Is there already a further ticket for this?

    class Foo {
         func bar(closure: (Self) -> Void) {
            ...
          }
    }

I don’t know, feel free to add one. The limitations on Self as a type in method signatures are: only return value if it is a class. See the discussion in the PR.

I filed SR-10121 to track that :)

2 Likes
class A {
    required init() {}
    func copy() -> Self {
        let copy = Self.init()
        return copy
    }
    
    var copied: Self {
        let copy = Self.init()
        return copy
    }
}

class B: A {
    override func copy() -> Self {
        let copy = super.copy() as! Self // supported
        return copy
    }
    
    override var copied: Self {
        let copy = super.copied as! Self // unsupported
        return copy
    }
}

Please file a Jira for this, include #Self in the title so someone can pick them up.

I filed SR-10135.

Thanks

The fix for SR-10135 merged a couple of days ago and should be available in the swift.org nightly builds by now. Please kick the tires and answer on the Jira or PR if you find any problems.

2 Likes

Filed an issues. I am I correct that this limitation exists because it was not yet lifted, otherwise I don't see why properties cannot be of type Self.

@johnno1962 since we cannot create nested types in protocols yet, Self on classes is the first occurrence of the dynamic type that can be captured by a nested type. Does this mean that nested types are (pseudo-)generic?

class Base {
  typealias _Self = Self
  struct PseudoGeneric {
    var dynamicBase: _Self
  }
}

If we could apply this pattern for nested types in protocols one day, this would be awesome.