True, but there are a few edge cases where Self simply does not work.

On classes the return type has the contract to return self.
Even if we get SE–0068, will Self work in generic context like showed in OP 
with Current?
#1 Using value semantics on classes means that the returned instance is a new 
instance different from self.

Assume this small protocol:

// Follow value semantics == immutability
protocol Cloned : class {
      func cloned() -> Self
}

class A : Cloned {
     func cloned() -> Self {
           return /* copy of self */ <— ERROR
     }
}
One could workaround the problem and use final, but what if the class meant to 
be subtypeable? Self simply does not work in this scenario. The only workaround 
here would be associatedtype T as the return type instead of Self, but is this 
really what we wanted to describe in our protocol. T could be anything else and 
we cannot constrain it like: associatedtype T : Self.

Either a static Self is needed or we need to remove the restriction that on the 
conforming non-final class we cannot overrider Self with the TypeName, like on 
any of it’s subtype.

\2# On non-final classes from the generic context something like this following 
snippet seems to be odd if Self is dynamic.

// What is the constraint here? `Self` is dynamic.  
// I might want to cast to `A` where `Self` in this case would be e.g.`NSObject`
// but the dynamic type of the current instance is `B`.
// The relationship might look like this: B : A : NSObject
// `Self` would refer to `B`, but `A` is not a subclass of `B`.
extension AReallyLongNonFinalClassName {
    func casted<T : Self>() -> T { ... }
}

// In contrast the proposed static `Self` as `Current`
extension AReallyLongNonFinalClassName {
    func casted<T : Current>() -> T { ... }
}


-- 
Adrian Zubarev
Sent with Airmail

Am 7. Januar 2017 um 18:34:38, Xiaodi Wu ([email protected]) schrieb:

`Self` _always_ refers to the dynamic type of `self`. It just happens to be 
that in the case of structs the dynamic type is the same as the static type. 
The idea of having a shorthand for the containing type (spelled #Self or 
StaticSelf) was discussed during consideration of SE-0068. The accepted version 
of the proposal rejects that idea, having adopted the position that "You will 
continue to specify full type names for any other use. Joe Groff writes, 'I 
don't think it's all that onerous to have to write ClassName.foo if that's 
really what you specifically mean.'"


On Sat, Jan 7, 2017 at 11:14 AM, thislooksfun via swift-evolution 
<[email protected]> wrote:
I like this idea, however, if I understand the proposal correctly, I think that 
the naming would make more sense the other way around. `Self` is, at least in 
my head, tied directly and statically to the enclosing type, where as `Current` 
sounds more dynamic, and could change from place-to-place.

-thislooksfun (tlf)

On Jan 7, 2017, at 4:38 AM, Adrian Zubarev via swift-evolution 
<[email protected]> wrote:

Hi Swift community,

I’d like to talk to about current Self keyword. If I’m not totally mistaken 
then the current Self has a few meanings:

Refer to the current type, or refer to the dynamic type for non-final classes 
inside containing type (SE–0068 - not yet implemented).
For non-final class types use Self as return type on the conforming super type 
(or return an instance of receiver Self).
Let me visualize the behaviors quickly in some short code snippet:

protocol Foo {
    func foo(_ f: Self) -> Self
}

class A : Foo {
    // forced to use `A` as parameter type and `Self` as return type
    func foo(_ f: A) -> Self { return self }
    // Returning `A()` would cause an error: Cannot convert return expression 
of type 'A' to return type 'Self'
    func bar() -> A { return A() /* or self */ }
    func zoo() -> Self { return /* only */ self }
}

class B : A {
    // Both is fine `B` or `Self` as the return type
    // If `B` is used you can return a different instance like `B()`
    // `Self` does only allow `self` to be used here
    override func foo(_ f: A) -> B { return self }
}

struct D : Foo {
    // No `Self` allowed here at all
    func foo(_ f: D) -> D { return self /* or D() */ }
}
The behavior of Self is a little magical, because it sometimes refers to the 
current type it is used in, or it has a contract of using self.

I propose of introducing a new keyword called Current to solve a few problems 
here.

Self on parameter types would be disallowed for protocol members, because 
conformances to that protocol already disallow that (see A above). Instead one 
would use Current and get the correct meaning.

protocol Boo {
    func boo(_ b: Current) -> Self
}
      
procotol Loo {
    func loo() -> Current
}
      
class X : Boo, Loo {
    func boo(_ b: X) -> Self { return self }
    func loo() -> X { return self /* or X() */ }
}
      
final class Y : Boo {
    func boo(_ b: X) -> Y { return self /* or Y */ }
}
Using Self inside the containing type would always mean as one would refer to 
the dynamic type, like the magical syntax function type(of:) does.

Current can only refer to the current containing type.

On classes Self has always the contract of returning self.

Self could be discouraged in favor of Current on value types, as a shorthand to 
refer to the containing type.

Generics could benefit from Current too:

extension AReallyLongNonFinalClassName {
    func casted<T : Current>() -> T { ... }
}
// `Self` wouldn't here, because it would refer to the dynamic type
#1 Would affect a lot of protocols which implies that it would affect ABI.

These are the first ideas I had in my mind. We can polish it further if it 
receives positive and constructive feedback.

Best regards, 




-- 
Adrian Zubarev
Sent with Airmail

_______________________________________________
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

Reply via email to