[Revision] [Pitch] Rename `T.Type`

just write code in playground:
struct MyStruct {
var t = 0

sizeof(MyStruct)

Compiler error:
Missing '.self' for reference to metatype of type 'MyStruct'

The metatype is from swift it self!

What the hell was the .self?

Jose Cheyo Jimenez via swift-evolution <swift-evolution@swift.org>于2016年7月24日
周日04:45写道:

···

I'm finding it really hard to see the advantage of this proposal with out
reconciling the possibility of .self going away. I think this should be
postponed after .self is reviewed in swift 4. Premature optimization imo.

On Jul 22, 2016, at 3:20 PM, David Hart via swift-evolution < > swift-evolution@swift.org> wrote:

Where do these double generics come from? Never saw them...

On 22 Jul 2016, at 17:54, Anton Zhilin <antonyzhilin@gmail.com> wrote:

2016-07-22 18:51 GMT+03:00 David Hart <david@hartbit.com>:

Isn't the solution to a lot of these issues allowing explicit
generalization instead of this meta type business?

And what would you suggest for "double generics" in initializers?
ExampleType<Int><Double>() // not good

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

···

On Jul 24, 2016, at 2:21 AM, Boris Wang <kona.ming@gmail.com> wrote:

just write code in playground:
struct MyStruct {
var t = 0

sizeof(MyStruct)

Compiler error:
Missing '.self' for reference to metatype of type 'MyStruct'

The metatype is from swift it self!

What the hell was the .self?

Jose Cheyo Jimenez via swift-evolution <swift-evolution@swift.org>于2016年7月24日 周日04:45写道:

I'm finding it really hard to see the advantage of this proposal with out reconciling the possibility of .self going away. I think this should be postponed after .self is reviewed in swift 4. Premature optimization imo.

On Jul 22, 2016, at 3:20 PM, David Hart via swift-evolution <swift-evolution@swift.org> wrote:

Where do these double generics come from? Never saw them...

On 22 Jul 2016, at 17:54, Anton Zhilin <antonyzhilin@gmail.com> wrote:

2016-07-22 18:51 GMT+03:00 David Hart <david@hartbit.com>:

Isn't the solution to a lot of these issues allowing explicit generalization instead of this meta type business?

And what would you suggest for "double generics" in initializers?
ExampleType<Int><Double>() // not good

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Boris, you should write `sizeof(MyStruct.self)` in your example. Removal of
`.self` is deferred from Swift 3.
SE lists are not the best place to learn about metatypes, but here is some
explanation:

···

2016-07-24 12:21 GMT+03:00 Boris Wang via swift-evolution < swift-evolution@swift.org>:

just write code in playground:
struct MyStruct {
var t = 0

sizeof(MyStruct)

Compiler error:
Missing '.self' for reference to metatype of type 'MyStruct'

The metatype is from swift it self!

What the hell was the .self?

Got it, thanks!
Anton Zhilin <antonyzhilin@gmail.com>于2016年7月24日 周日17:32写道:

···

2016-07-24 12:21 GMT+03:00 Boris Wang via swift-evolution <
swift-evolution@swift.org>:

just write code in playground:
struct MyStruct {
var t = 0

sizeof(MyStruct)

Compiler error:
Missing '.self' for reference to metatype of type 'MyStruct'

The metatype is from swift it self!

What the hell was the .self?

Boris, you should write `sizeof(MyStruct.self)` in your example. Removal
of `.self` is deferred from Swift 3.
SE lists are not the best place to learn about metatypes, but here is some
explanation:
metatypes-explanation.md · GitHub

We’ve submitted a PR. [Revised SE-0126] [Ready for review] Refactor metatypes by DevAndArtist · Pull Request #466 · apple/swift-evolution · GitHub

The proposal was refactored completely.

Introduction

This proposal removes .Type and .Protocol in favor of two generic-style syntaxes and aligns global type(of:) function (SE–0096) to match the changes.

Swift-evolution threads:

[Revision] [Pitch] Rename T.Type
[Review] SE–0126: Refactor Metatypes, repurpose T[dot]self and Mirror
[Proposal] Refactor Metatypes, repurpose T[dot]self and Mirror
[Discussion] Seal T.Type into Type<T>
Motivation

Every type T has an instance, accessible through T.self, which represents the type itself. Like all instances in Swift, this “type instance” itself has a type, which is referred to as its “metatype”. The metatype of T is written T.Type. The instance members of the metatype are the same as the static or class members of the type.

Metatypes have subtype relationships which reflect the types they represent. For instance, given these types:

protocol Proto {}
class Base {}
class Derived: Base, Proto {}
Derived.Type is a subtype of both Base.Type and Proto.Type (and Any.Type). That means that Derived.self can be used anywhere a Derived.Type, Base.Type, Proto.Type, or Any.Type is called for.

Unfortunately, this simple picture is complicated by protocols. Proto.self is actually of type Proto.Protocol, not type Proto.Type. This is necessary because the protocol does not, and cannot, conform to itself; it requires conforming types to provide static members, but it doesn’t actually provide those members itself. Proto.Type still exists, but it is the supertype of all types conforming to the protocol.

Making this worse, a generic type always uses T.Type to refer to the type of T.self. So when Proto is bound to a generic parameter P, P.Type is the same as Proto.Protocol.

This shifting of types is complicated and confusing; we seek to clean up this area.

We also believe that, in the long term, the dot syntax will prevent us from implementing certain future enhancements that might be valuable:

Moving the implementation of metatypes at least partly into the standard library.
Adding members available on all type instances for features like read-write reflection or memory layout information.
Conforming metatypes to protocols like Hashable or CustomStringConvertible.
Offering straightforward syntaxes for dynamic features like looking up types by name.
Proposed solution

We abolish .Type and .Protocol in favor of two generic-style syntaxes:

Type<T> is the concrete type of T.self. A Type<T> can only ever accept that one specific type, not any of its subtypes. If T is a protocol P, than the only supertype for Type<P> is Subtype<Any>. To be crystal clear here, Type<P> is not a subtype of Subtype<P>.

Subtype<T> is the supertype of all Types whose instances are subtypes of T. If T is a class, Subtype<T> would accept a Type for any of its subclasses. If T is a protocol, Subtype<T> would accept a Type for any conforming concrete type.

In this new notation, some of our existing standard library functions would have signatures like:

func unsafeBitCast<T, U>(_: T, to type: Type<U>) -> U
func sizeof<T>(_: Type<T>) -> Int
func ==(t0: Subtype<Any>?, t1: Subtype<Any>?) -> Bool
func type<T>(of: T) -> Subtype<T> // SE-0096
That last example, type(of:), is rather interesting, because it is actually a magic syntax rather than a function. We propose to align this syntax with Type and Subtype by renaming it to Subtype(of:). We believe this is clearer about both the type and meaning of the operation.

let instance: NSObject = NSString()
let class: Subtype<NSObject> = Subtype(of: instance)

print(class) // => NSString
Example: visual metatype relationship
Example: generic functions
Future Directions

We could allow extensions on Type and perhaps on Subtype to add members or conform them to protocols. This could allow us to remove some standard library hacks, like the non-Equatable-related == operators for types.

It may be possible to implement parts of Type as a fairly ordinary final class, moving code from the runtime into the standard library.

We could offer a Subtype(ofType: Type<T>, named: String) pseudo-initializer which would allow type-safe access to classes by name.

We could offer other reflection and dynamic features on Type and Subtype.

We could move the MemoryLayout members into Type (presumably prefixed), removing the rather artificial MemoryLayout enum.

Along with other generics enhancements, there may be a use for a Subprotocol<T> syntax for any protocol requiring conformance to protocol T.

Impact on existing code

This is a source-breaking change that can be automated by a migrator.

We suggest the following migration process; this can differ from the final migration process implemented by the core team if this proposal will be accepted:

Any.Type is migrated to Subtype<Any>.
If T.Type is in function parameter, where T is a generic type parameter, then it’s migrated to Type<T>.
Every T.Protocol will be replaced with Type<T>.
Every T.Type in a dynamic cast will be replaced with Subtype<T>.
If static members are called on a metatype instance, then this instance is migrated to Subtype<T>.
Return types of functions are migrated to Subtype<T>.
Variable declarations is migrated to Subtype<T>.
Alternatives considered

Other names for Type and Subtype were considered:

Type: SpecificType, Metatype or ExactType.
Subtype: Supertype, Base, BaseType, ExistentialType or TypeProtocol.
Alternatively the pseudo initializer Subtype(of:) could remain as a global function:

public func subtype<T>(of instance: T) -> Subtype<T>

···

--
Adrian Zubarev
Sent with Airmail

Fixed PR: [Revised SE-0126] [Ready for review] Refactor metatypes by DevAndArtist · Pull Request #468 · apple/swift-evolution · GitHub

···

--
Adrian Zubarev
Sent with Airmail

Am 25. Juli 2016 um 21:35:22, Adrian Zubarev (adrian.zubarev@devandartist.com) schrieb:

We’ve submitted a PR. [Revised SE-0126] [Ready for review] Refactor metatypes by DevAndArtist · Pull Request #466 · apple/swift-evolution · GitHub

The proposal was refactored completely.

Introduction

This proposal removes .Type and .Protocol in favor of two generic-style syntaxes and aligns global type(of:) function (SE–0096) to match the changes.

Swift-evolution threads:

[Revision] [Pitch] Rename T.Type
[Review] SE–0126: Refactor Metatypes, repurpose T[dot]self and Mirror
[Proposal] Refactor Metatypes, repurpose T[dot]self and Mirror
[Discussion] Seal T.Type into Type<T>
Motivation

Every type T has an instance, accessible through T.self, which represents the type itself. Like all instances in Swift, this “type instance” itself has a type, which is referred to as its “metatype”. The metatype of T is written T.Type. The instance members of the metatype are the same as the static or class members of the type.

Metatypes have subtype relationships which reflect the types they represent. For instance, given these types:

protocol Proto {}
class Base {}
class Derived: Base, Proto {}
Derived.Type is a subtype of both Base.Type and Proto.Type (and Any.Type). That means that Derived.self can be used anywhere a Derived.Type, Base.Type, Proto.Type, or Any.Type is called for.

Unfortunately, this simple picture is complicated by protocols. Proto.self is actually of type Proto.Protocol, not type Proto.Type. This is necessary because the protocol does not, and cannot, conform to itself; it requires conforming types to provide static members, but it doesn’t actually provide those members itself. Proto.Type still exists, but it is the supertype of all types conforming to the protocol.

Making this worse, a generic type always uses T.Type to refer to the type of T.self. So when Proto is bound to a generic parameter P, P.Type is the same as Proto.Protocol.

This shifting of types is complicated and confusing; we seek to clean up this area.

We also believe that, in the long term, the dot syntax will prevent us from implementing certain future enhancements that might be valuable:

Moving the implementation of metatypes at least partly into the standard library.
Adding members available on all type instances for features like read-write reflection or memory layout information.
Conforming metatypes to protocols like Hashable or CustomStringConvertible.
Offering straightforward syntaxes for dynamic features like looking up types by name.
Proposed solution

We abolish .Type and .Protocol in favor of two generic-style syntaxes:

Type<T> is the concrete type of T.self. A Type<T> can only ever accept that one specific type, not any of its subtypes. If T is a protocol P, than the only supertype for Type<P> is Subtype<Any>. To be crystal clear here, Type<P> is not a subtype of Subtype<P>.

Subtype<T> is the supertype of all Types whose instances are subtypes of T. If T is a class, Subtype<T> would accept a Type for any of its subclasses. If T is a protocol, Subtype<T> would accept a Type for any conforming concrete type.

In this new notation, some of our existing standard library functions would have signatures like:

func unsafeBitCast<T, U>(_: T, to type: Type<U>) -> U
func sizeof<T>(_: Type<T>) -> Int
func ==(t0: Subtype<Any>?, t1: Subtype<Any>?) -> Bool
func type<T>(of: T) -> Subtype<T> // SE-0096
That last example, type(of:), is rather interesting, because it is actually a magic syntax rather than a function. We propose to align this syntax with Type and Subtype by renaming it to Subtype(of:). We believe this is clearer about both the type and meaning of the operation.

let instance: NSObject = NSString()
let class: Subtype<NSObject> = Subtype(of: instance)

print(class) // => NSString
Example: visual metatype relationship
Example: generic functions
Future Directions

We could allow extensions on Type and perhaps on Subtype to add members or conform them to protocols. This could allow us to remove some standard library hacks, like the non-Equatable-related == operators for types.

It may be possible to implement parts of Type as a fairly ordinary final class, moving code from the runtime into the standard library.

We could offer a Subtype(ofType: Type<T>, named: String) pseudo-initializer which would allow type-safe access to classes by name.

We could offer other reflection and dynamic features on Type and Subtype.

We could move the MemoryLayout members into Type (presumably prefixed), removing the rather artificial MemoryLayout enum.

Along with other generics enhancements, there may be a use for a Subprotocol<T> syntax for any protocol requiring conformance to protocol T.

Impact on existing code

This is a source-breaking change that can be automated by a migrator.

We suggest the following migration process; this can differ from the final migration process implemented by the core team if this proposal will be accepted:

Any.Type is migrated to Subtype<Any>.
If T.Type is in function parameter, where T is a generic type parameter, then it’s migrated to Type<T>.
Every T.Protocol will be replaced with Type<T>.
Every T.Type in a dynamic cast will be replaced with Subtype<T>.
If static members are called on a metatype instance, then this instance is migrated to Subtype<T>.
Return types of functions are migrated to Subtype<T>.
Variable declarations is migrated to Subtype<T>.
Alternatives considered

Other names for Type and Subtype were considered:

Type: SpecificType, Metatype or ExactType.
Subtype: Supertype, Base, BaseType, ExistentialType or TypeProtocol.
Alternatively the pseudo initializer Subtype(of:) could remain as a global function:

public func subtype<T>(of instance: T) -> Subtype<T>

--
Adrian Zubarev
Sent with Airmail

PR closed, we’ll come back for Swift 3.1. ;)

···

--
Adrian Zubarev
Sent with Airmail

Am 25. Juli 2016 um 23:08:26, Adrian Zubarev (adrian.zubarev@devandartist.com) schrieb:

Fixed PR: [Revised SE-0126] [Ready for review] Refactor metatypes by DevAndArtist · Pull Request #468 · apple/swift-evolution · GitHub

--
Adrian Zubarev
Sent with Airmail

Am 25. Juli 2016 um 21:35:22, Adrian Zubarev (adrian.zubarev@devandartist.com) schrieb:

We’ve submitted a PR. [Revised SE-0126] [Ready for review] Refactor metatypes by DevAndArtist · Pull Request #466 · apple/swift-evolution · GitHub

The proposal was refactored completely.

Introduction

This proposal removes .Type and .Protocol in favor of two generic-style syntaxes and aligns global type(of:) function (SE–0096) to match the changes.

Swift-evolution threads:

[Revision] [Pitch] Rename T.Type
[Review] SE–0126: Refactor Metatypes, repurpose T[dot]self and Mirror
[Proposal] Refactor Metatypes, repurpose T[dot]self and Mirror
[Discussion] Seal T.Type into Type<T>
Motivation

Every type T has an instance, accessible through T.self, which represents the type itself. Like all instances in Swift, this “type instance” itself has a type, which is referred to as its “metatype”. The metatype of T is written T.Type. The instance members of the metatype are the same as the static or class members of the type.

Metatypes have subtype relationships which reflect the types they represent. For instance, given these types:

protocol Proto {}
class Base {}
class Derived: Base, Proto {}
Derived.Type is a subtype of both Base.Type and Proto.Type (and Any.Type). That means that Derived.self can be used anywhere a Derived.Type, Base.Type, Proto.Type, or Any.Type is called for.

Unfortunately, this simple picture is complicated by protocols. Proto.self is actually of type Proto.Protocol, not type Proto.Type. This is necessary because the protocol does not, and cannot, conform to itself; it requires conforming types to provide static members, but it doesn’t actually provide those members itself. Proto.Type still exists, but it is the supertype of all types conforming to the protocol.

Making this worse, a generic type always uses T.Type to refer to the type of T.self. So when Proto is bound to a generic parameter P, P.Type is the same as Proto.Protocol.

This shifting of types is complicated and confusing; we seek to clean up this area.

We also believe that, in the long term, the dot syntax will prevent us from implementing certain future enhancements that might be valuable:

Moving the implementation of metatypes at least partly into the standard library.
Adding members available on all type instances for features like read-write reflection or memory layout information.
Conforming metatypes to protocols like Hashable or CustomStringConvertible.
Offering straightforward syntaxes for dynamic features like looking up types by name.
Proposed solution

We abolish .Type and .Protocol in favor of two generic-style syntaxes:

Type<T> is the concrete type of T.self. A Type<T> can only ever accept that one specific type, not any of its subtypes. If T is a protocol P, than the only supertype for Type<P> is Subtype<Any>. To be crystal clear here, Type<P> is not a subtype of Subtype<P>.

Subtype<T> is the supertype of all Types whose instances are subtypes of T. If T is a class, Subtype<T> would accept a Type for any of its subclasses. If T is a protocol, Subtype<T> would accept a Type for any conforming concrete type.

In this new notation, some of our existing standard library functions would have signatures like:

func unsafeBitCast<T, U>(_: T, to type: Type<U>) -> U
func sizeof<T>(_: Type<T>) -> Int
func ==(t0: Subtype<Any>?, t1: Subtype<Any>?) -> Bool
func type<T>(of: T) -> Subtype<T> // SE-0096
That last example, type(of:), is rather interesting, because it is actually a magic syntax rather than a function. We propose to align this syntax with Type and Subtype by renaming it to Subtype(of:). We believe this is clearer about both the type and meaning of the operation.

let instance: NSObject = NSString()
let class: Subtype<NSObject> = Subtype(of: instance)

print(class) // => NSString
Example: visual metatype relationship
Example: generic functions
Future Directions

We could allow extensions on Type and perhaps on Subtype to add members or conform them to protocols. This could allow us to remove some standard library hacks, like the non-Equatable-related == operators for types.

It may be possible to implement parts of Type as a fairly ordinary final class, moving code from the runtime into the standard library.

We could offer a Subtype(ofType: Type<T>, named: String) pseudo-initializer which would allow type-safe access to classes by name.

We could offer other reflection and dynamic features on Type and Subtype.

We could move the MemoryLayout members into Type (presumably prefixed), removing the rather artificial MemoryLayout enum.

Along with other generics enhancements, there may be a use for a Subprotocol<T> syntax for any protocol requiring conformance to protocol T.

Impact on existing code

This is a source-breaking change that can be automated by a migrator.

We suggest the following migration process; this can differ from the final migration process implemented by the core team if this proposal will be accepted:

Any.Type is migrated to Subtype<Any>.
If T.Type is in function parameter, where T is a generic type parameter, then it’s migrated to Type<T>.
Every T.Protocol will be replaced with Type<T>.
Every T.Type in a dynamic cast will be replaced with Subtype<T>.
If static members are called on a metatype instance, then this instance is migrated to Subtype<T>.
Return types of functions are migrated to Subtype<T>.
Variable declarations is migrated to Subtype<T>.
Alternatives considered

Other names for Type and Subtype were considered:

Type: SpecificType, Metatype or ExactType.
Subtype: Supertype, Base, BaseType, ExistentialType or TypeProtocol.
Alternatively the pseudo initializer Subtype(of:) could remain as a global function:

public func subtype<T>(of instance: T) -> Subtype<T>

--
Adrian Zubarev
Sent with Airmail