[swift-evolution] [Draft] Introducing StaticSelf, an Invariant Self

Vladimir.S svabox at gmail.com
Fri May 13 02:35:58 CDT 2016


Why did you decide to drop the `#` ? As `StaticSelf` will be resolved on 
compilation time like #file etc ? I feel like this is inconsistent solution.

Also, do you expect this will work:

protocol A {
   func g()->StaticSelf
}

class B: A {
   func g()->StaticSelf {return B()}
}

class C: B {
   //func f(s: C) {}
}

func x(a: A ){
     var xx : A = a.g() // ?
     print(xx)
}

func z<T: A>(t: T) {
     let u = t.g() // ?
     print(u)
}

let c = C()
z(c)
x(c)


On 13.05.2016 3:49, Matthew Johnson via swift-evolution wrote:
> Erica Sadun and I have written a proposal are following up the recent
> discussion thread "[RFC] #Self” with a proposal to introduce StaticSelf, an
> invariant Self.
>
> The recent discussion can be found
> here: http://thread.gmane.org/gmane.comp.lang.swift.evolution/16565
>
> The proposal can be found
> here: https://github.com/anandabits/swift-evolution/blob/static-self/proposals/NNNN-static-self.md
>
> We look forward to continuing the discussion.  We plan to submit a PR in
> the near future after incorporating your final feedback.
>
> Thanks,
> Matthew
>
>
>   Introducing StaticSelf, an Invariant Self
>
>   * Proposal: TBD
>   * Authors: Matthew Johnson <https://github.com/anandabits>, Erica Sadun
>     <https://github.com/erica>
>   * Status: TBD
>   * Review manager: TBD
>
>
>     Introduction
>
> This proposal introduces a new keyword that provides consistent invariant
> type semantics in all contexts.
>
> /The Swift-evolution thread about this topic can be found here: [RFC] #Self
> <http://thread.gmane.org/gmane.comp.lang.swift.evolution/16565>/
>
>
>     Motivation
>
> The distinction between covariant and non-covariant type references come
> into play when
> conforming non-final classes to protocols. Fixing a protocol requirement to
> a covarying type
> means that a method returning |Self| must be overriden by all subclasses in
> order to return
> the correct, matching type.
>
> This proposal builds on the covariant construct |Self| accepted in SE–0068
> <https://github.com/apple/swift-evolution/blob/master/proposals/0068-universal-self.md>
> to introduce an invariant type identifier. It enables protocol declarations
> to consistently
> refer to a type that is fixed at compile time. This ensures that subclasses
> can inherit
> protocol implementations without having to re-implement that code at each
> level of
> inheritance.
>
> Under this proposal, a new identifier keyword is fixed in use /at the point
> of protocol conformance/
> to the static type of that construct.
>
> |class A: MyProtocol|
>
> The invariant |StaticSelf| identifier will always refer to |A|,
> unlike |Self|, which is covarying and refers to
> the type of the actual instance. Since multiple inheritance for
> non-protocol types is disallowed,
> this establishes this invariant type identifier with no possibility for
> conflict.
>
> Consider the following example, under the current system:
>
> |protocol StringCreatable { static func createWithString(s: String) -> Self
> } extension NSURL: StringCreatable { // cannot conform because NSURL is
> non-final // error: method 'createWithString' in non-final class 'NSURL'
> must return `Self` to conform to protocol 'A' }|
>
> Introducing a static, invariant version of |Self| permits the desired
> conformance:
>
> |protocol StringCreatable { static func createWithString(s: String) ->
> StaticSelf } 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 { // ... } }|
>
>
>       Additional Utility
>
> The utility of |StaticSelf| is not limited to protocols. A secondary use
> enables code to refer to the lexical context’s current type without
> explicitly mentioning its name. This provides a useful shortcut when
> referencing static type members with especially long names and when
> re-purposing code between types.
>
> |class StructWithAVeryLongName { static func foo() -> String { // ... } func
> bar() { // ... let s = StaticSelf.foo() // } }|
>
>
>     Detailed Design
>
> This proposal introduces |StaticSelf|, a new keyword that may be used in
> protocols to refer to the invariant static type of a conforming
> construct. |StaticSelf| may also be used in the lexical context of any type
> declaration. In such use, the keyword is identical to spelling out the full
> name of that type.
>
>
>     Impact on existing code
>
> Being additive, there should be no impact on existing code.
>
>
>     Alternatives considered
>
> The keyword is not fixed at this time. Alternatives that have been
> discussed include |StaticType|, |InvariantSelf|, |SelfType|, or |Type|. The
> community is welcome to bikeshed on the most clear and concise name for
> this keyword.
>
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>


More information about the swift-evolution mailing list