Sent from my iPad
> On May 18, 2016, at 9:57 PM, Patrick Smith <[email protected]> wrote: > > I think the distinction between StaticSelf and Self will be very confusing to > newcomers. > > So the only reason why we must use StaticSelf instead of Self here is because > we want NSURL to conform, and it isn’t final? > > protocol StringCreatable { > static func createWithString(s: String) -> StaticSelf > } > > I find it a code smell that this would affect the protocol and not the class. > > Why couldn’t you have this? > > protocol StringCreatable { > static func createWithString(s: String) -> Self > } > > extension NSURL: StringCreatable { > // can now conform conform because NSURL is fixed and matches the static > // type of the conforming construct. Subclasses need not re-implement > // NOTE: the return type can be declared as StaticSelf *or* as NSURL > // they are interchangeable > static func createWithString(s: String) -> StaticSelf { > // ... > } > } > You can't do this because the Self return type in the protocol requirement specifically *requires* all subclasses to override the method and return an instance of the subclass type. Nevertheless, we have identified a workaround that is similar enough to StaticSelf that we have abandoned the proposal. Please see The last couple posts in this thread if you're interested in the details. > > >> On 19 May 2016, at 3:37 AM, Erica Sadun via swift-evolution >> <[email protected]> wrote: >> >> As a wrap-up of the topic, I've updated our original draft with Nicola S's >> resolution. >> >> https://gist.github.com/erica/995af96a0de2f2f3dc419935e8140927 >> >> -- E >> >> >>>> On May 14, 2016, at 8:35 AM, Matthew Johnson via swift-evolution >>>> <[email protected]> wrote: >>>> >>>> >>>> On May 14, 2016, at 12:55 AM, Nicola Salmoria via swift-evolution >>>> <[email protected]> wrote: >>>> >>>> Matthew Johnson via swift-evolution <swift-evolution@...> writes: >>>> >>>>> I agree it’s a bit tricky. But that’s better than not possible at all. >>>> You just need a typealias and a same type constraint to make this work as >>>> expected / desired: >>>>> >>>>> >>>>> protocol Makable { >>>>> >>>>> typealias RootMakable = StaticSelf >>>>> static func make(value: Int) -> StaticSelf >>>>> } >>>>> >>>>> func makeWithZero<T: Makable where T == T.RootMakable>(x: Int) -> T { >>>>> return T.make(value: 0) // works now >>>>> } >>>>> >>>>> >>>>> Now that we have a typealias we can refer to the binding of StaticSelf and >>>> constrain it as necessary for whatever purpose we have in mind. In some >>>> cases that will be a same type constraint so that our code works properly >>>> with class clusters. I don’t have concrete examples of other use cases but >>>> can imagine use cases constraining the typealias to a protocol, for >>>> example. >>>> >>>> You can do that today: >>>> >>>> protocol Makable { >>>> associatedtype MadeType >>>> static func make(value: Int) -> MadeType >>>> } >>>> >>>> func makeWithZero<T: Makable where T == T.MadeType>(x: Int) -> T { >>>> return T.make(value: 0) >>>> } >>>> >>>> You can't currently constrain MadeType to be the same as the conforming >>>> type, but, does it matter? What kind of extra guarantees would that give, >>>> since you need to add the extra constraint anyway in generic code? >>> >>> Wow, this is pretty cool. Thank you very much for pointing this out Nicola! >>> >>> I haven’t seen this approach to solving the problem. Given the amount of >>> discussion this problem has received I am surprised nobody has shared this >>> solution yet. I just checked in Xcode 7.3 and it works there. It isn’t >>> dependent on any pre-release features. >>> >>> Instead of using StaticSelf under the current proposal: >>> >>> protocol StringInitializable { >>> static func initializeWith(string: String) -> StaticSelf >>> } >>> >>> We just add an associatedtype defaulted to Self: >>> >>> protocol StringInitializable { >>> associatedtype Initialized = Self // where Self: Initialized >>> static func initializeWith(string: String) -> Initialized >>> } >>> >>> extension NSURL: StringInitializable { >>> static func initializeWith(string: String) -> NSURL { >>> return NSURL() >>> } >>> } >>> >>> func makeWith<T: StringInitializable where T == T.Initialized>(string: >>> String) -> T { >>> return T.initializeWith(string: string) >>> } >>> >>> There are two minor downsides to this approach: >>> >>> 1. You can’t copy and paste the method signature. >>> 2. You can theoretically conform a type completely unrelated to >>> `Initialized` to the protocol, thus violating the semantics. >>> >>> I think we can live with these downsides. Maybe the `Self: Initialized` >>> will be possible someday. That would be pretty close to StaticSelf. The >>> only difference would be that subclasses still have flexibility to override >>> with their own type. >>> >>> Now that a reasonable way to do this with existing language features has >>> been identified I will withdraw this proposal. If this approach doesn’t >>> address use cases others have in mind for StaticSelf please speak up! >>> >>> Doug, if you’re reading this, does the `where Self: Initialized` (i.e. >>> arbitrary subclass constraints) fall into the scope of your “completing >>> generics” manifesto? This is a concrete use case that would utilize >>> subclass constraints. >>> >>> -Matthew >>> >>> >>>> >>>> Nicola >>>> _______________________________________________ >>>> swift-evolution mailing list >>>> [email protected] >>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>> >>> _______________________________________________ >>> swift-evolution mailing list >>> [email protected] >>> https://lists.swift.org/mailman/listinfo/swift-evolution >> >> _______________________________________________ >> swift-evolution mailing list >> [email protected] >> https://lists.swift.org/mailman/listinfo/swift-evolution >
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
