Unify `static` and `class` keywords


(Ling Wang) #1

The idea is simple but the reasoning is long. So please bear with me.
You can read on github for a better reading experience:
https://github.com/an0/swift-evolution/blob/master/proposals/NNNN-unify-static-and-class-keywords.md.

## Introduction

The coexistence of `static` and `class` keywords for declaring type
properties and methods is confusing and causes inconsistency between
type and instance member declarations. This document reasons why we
don’t need both and suggests we unify them with a better keyword
`type`.

## Motivation

### Confusion

One “language enhancement” of [Swift
1.2](https://developer.apple.com/library/ios/releasenotes/DeveloperTools/RN-Xcode/Chapters/xc6_release_notes.html#//apple_ref/doc/uid/TP40001051-CH4-SW6)
is:

“static” methods and properties are now allowed in classes (as an alias for class final). You are now allowed to declare static stored properties in classes, which have global storage and are lazily initialized on first access (like global variables). Protocols now declare type requirements as static requirements instead of declaring them as class requirements. (17198298)

If even the Swift team itself has difficulties in picking one from the
two and had to revert its initial decision after several revisions, we
know these keywords are indeed confusing.

So now protocols use `static` to declare type methods, when a class
adapts such protocols, should it implement those static methods, as
static methods or class methods?

But static means final, right? Does it mean we can not override these
methods in subclasses of the conforming class?

These kinds of unnecessary confusion and hesitation should be
resolved, and could if this proposal is implemented.

### Unnecessary and inconsistent differentiation

The `class` keyword is only used in classes. In the current
implementation of Swift the differences between `class` and `static`
are:

1. Class properties can only be calculated properties but not stored properties.
2. Class methods(also calculated properties) are dynamically
dispatched while static ones are statically dispatched.

If we can eliminate the differences or find better ways to
differentiate we can use one unified keyword instead for declaring
type properties and methods.

Let’s see.

#### Class stored properties VS. static stored properties

If you use the `class` keyword to declare a stored property in a class
you will get this compiling error:

class stored properties not yet supported in classes; did you mean 'static'?

So what are class stored properties? How are they different from
static stored properties?

As far as I know, class stored properties, if ever implemented in
Swift, “would be what Ruby calls ‘class instance
variables’”.<sup>[1](https://twitter.com/UINT_MIN/status/584104757117095936)</sup>

So what are class instance variables?

The best explanation I can find is this
[one](http://martinfowler.com/bliki/ClassInstanceVariable.html) from
Martin Fowler.

Do we really want this feature in Swift? “If we didn't already have
these, would we add them to Swift 3?"

I strongly believe we won’t add it to Swift 3. Actually I believe we
will never add it to Swift, because its use cases are so rare which is
also why it hasn’t been implemented so far in Swift.

If we agree we are not going to support class stored properties, there
is and will be only one kind of stored properties for types and we
only need one keyword to declare such properties.

#### Class methods VS. static methods

*Since calculated properties are also methods in essence they are also
covered by this section.*

The only difference is how methods are dispatched.

Let’s see [how we handle it for instance
methods](https://developer.apple.com/swift/blog/?id=27):

* Methods are overridable hence dynamically dispatched by default.
* In performance critical code use these techniques to restrict this
dynamic behavior when it isn’t needed to improve performance:

    1. Use the `final` keyword when we know that a declaration does
not need to be overridden.
    2. Infer `final` on declarations referenced in one file by
applying the `private` keyword.
    3. Use `Whole Module Optimization` to infer `final` on `internal`
declarations.

So why abandon this whole system to use another totally different one
for differentiating `static dispatch` and `dynamic dispatch` for type
methods?

If we reuse this system for type methods, not only can we have a
consistent design for both instance and type methods, but also we can
get rid of the last place where two keywords for type member
declarations are needed.

## Proposed solution

1. Use the keyword `type` to declare type properties and methods.
2. Type properties and methods are overridable hence dynamically
dispatched by default. Use the `final` keyword or inferred `final` to
make them final and statically dispatched, just like instance
properties and methods.
3. Type properties can be stored or calculated, just like instance properties.

As you can see, it is a very simple and elegant design:

* Just a single keyword `type` to differentiate type member
declarations from instance member declarations. `type` is a good
keyword because:

    1. It is consistent with the wording of the concepts of `type
properties` and `type methods`.
    2. It is never used as a keyword before in Swift, Objective-C or
C. There will be no conflicts or overloading of it meanings.
* Except for that, how things are declared, differentiated and
optimized are exactly the same in both type and instance world. Very
consistent.

## Comparison with current design

* Dynamic Dispatch VS. Static Dispatch

// Old
class Foo {
    func dynamicInstanceMethod() {}
    final func staticInstanceMethod() {}

    class func dynamicTypeMethod() {}
    static func staticTypeMethod() {}
}
// New
class Foo {
    func dynamicInstanceMethod() {}
    final func staticInstanceMethod() {}

    type func dynamicTypeMethod() {}
    final type func staticTypeMethod() {}
}

* Stored Properties VS. Calculated Properties

// Old
class Bar {
    static let i = 1

    class var j: Int {
        return 1
    }
}
// New
class Bar {
    type let i = 1

    type var j: Int {
        return 1
    }
}

* Struct Implementation VS. Class Implementation of Protocol

// Old
protocol P {
    static func foo()
}

struct S: P {
    static func foo() {}
}

class C: P {
    class func foo() {}
}
// New
protocol P {
    type func foo()
}

struct S: P {
    type func foo() {}
}

class C: P {
    type func foo() {}
}

## Impact on existing code

With the help of a good migration tool, there will be no impact on
existing code at all. And the migration rules are very clear and
simple:

* Map `static` to `type` in protocols.
* Map `static` to `type` in structs and enums.
* Map `class` to `type` and `static` to `final type` in classes.

One concern I can think of is: because type methods are dynamically
dispatched by default in the new design, will we forget to do the
`final` optimization so the general performance of Swift code become
worse?

I think it is probably true. But we also forget to do the `final`
optimization for instance methods from time to time. Since there are
way more instance methods than type methods in most code the
performance impact will be very small. Maybe this change is a good
opportunity to remind us to do the `final` optimization for instance
methods thus even results in a better general performance.

And don’t forget we have the tools to automatically infer `final` for
us in many cases if we write the proper code and use the proper
compiler features.

After all, it is mainly on us to write good code to produce good final
products. If the system is consistent we’ll have better chances to
master it and use it properly.

## Alternatives considered

Alternatively we could:
* Keep using `static` and `class` keywords.
* Keep the confusion when implementing `static` protocol requirements
using `class` properties and methods in conforming classes.
* Keep the inconsistency between type member declarations and instance
member declarations.
* Keep overloading meanings on the `static` keyword that is already
historically overloaded in C and Objective-C with which Swift must mix
and match.


(Ling Wang) #2

`type` is the best I can come up with so far. Using `type` to declare type members inside types is completely parallel with using `class` to declare class members inside classes, so conceptually it should be easy to accept. It may look a bit uncomfortable at first simply because it is new and different, especially to those with C++ and Java experiences.

···

On Dec 7, 2015, at 11:01 AM, David Hart <david@hartbit.com> wrote:

I really like this proposition, but I'm not a fan of the keyword, but can't think of anything better right now...

On 07 Dec 2015, at 17:13, an0 via swift-evolution <swift-evolution@swift.org> wrote:

The idea is simple but the reasoning is long. So please bear with me.
You can read on github for a better reading experience:
https://github.com/an0/swift-evolution/blob/master/proposals/NNNN-unify-static-and-class-keywords.md.

## Introduction

The coexistence of `static` and `class` keywords for declaring type
properties and methods is confusing and causes inconsistency between
type and instance member declarations. This document reasons why we
don’t need both and suggests we unify them with a better keyword
`type`.

## Motivation

### Confusion

One “language enhancement” of [Swift
1.2](https://developer.apple.com/library/ios/releasenotes/DeveloperTools/RN-Xcode/Chapters/xc6_release_notes.html#//apple_ref/doc/uid/TP40001051-CH4-SW6)
is:

“static” methods and properties are now allowed in classes (as an alias for class final). You are now allowed to declare static stored properties in classes, which have global storage and are lazily initialized on first access (like global variables). Protocols now declare type requirements as static requirements instead of declaring them as class requirements. (17198298)

If even the Swift team itself has difficulties in picking one from the
two and had to revert its initial decision after several revisions, we
know these keywords are indeed confusing.

So now protocols use `static` to declare type methods, when a class
adapts such protocols, should it implement those static methods, as
static methods or class methods?

But static means final, right? Does it mean we can not override these
methods in subclasses of the conforming class?

These kinds of unnecessary confusion and hesitation should be
resolved, and could if this proposal is implemented.

### Unnecessary and inconsistent differentiation

The `class` keyword is only used in classes. In the current
implementation of Swift the differences between `class` and `static`
are:

1. Class properties can only be calculated properties but not stored properties.
2. Class methods(also calculated properties) are dynamically
dispatched while static ones are statically dispatched.

If we can eliminate the differences or find better ways to
differentiate we can use one unified keyword instead for declaring
type properties and methods.

Let’s see.

#### Class stored properties VS. static stored properties

If you use the `class` keyword to declare a stored property in a class
you will get this compiling error:

class stored properties not yet supported in classes; did you mean 'static'?

So what are class stored properties? How are they different from
static stored properties?

As far as I know, class stored properties, if ever implemented in
Swift, “would be what Ruby calls ‘class instance
variables’”.<sup>[1](https://twitter.com/UINT_MIN/status/584104757117095936)</sup>

So what are class instance variables?

The best explanation I can find is this
[one](http://martinfowler.com/bliki/ClassInstanceVariable.html) from
Martin Fowler.

Do we really want this feature in Swift? “If we didn't already have
these, would we add them to Swift 3?"

I strongly believe we won’t add it to Swift 3. Actually I believe we
will never add it to Swift, because its use cases are so rare which is
also why it hasn’t been implemented so far in Swift.

If we agree we are not going to support class stored properties, there
is and will be only one kind of stored properties for types and we
only need one keyword to declare such properties.

#### Class methods VS. static methods

*Since calculated properties are also methods in essence they are also
covered by this section.*

The only difference is how methods are dispatched.

Let’s see [how we handle it for instance
methods](https://developer.apple.com/swift/blog/?id=27):

* Methods are overridable hence dynamically dispatched by default.
* In performance critical code use these techniques to restrict this
dynamic behavior when it isn’t needed to improve performance:

  1. Use the `final` keyword when we know that a declaration does
not need to be overridden.
  2. Infer `final` on declarations referenced in one file by
applying the `private` keyword.
  3. Use `Whole Module Optimization` to infer `final` on `internal`
declarations.

So why abandon this whole system to use another totally different one
for differentiating `static dispatch` and `dynamic dispatch` for type
methods?

If we reuse this system for type methods, not only can we have a
consistent design for both instance and type methods, but also we can
get rid of the last place where two keywords for type member
declarations are needed.

## Proposed solution

1. Use the keyword `type` to declare type properties and methods.
2. Type properties and methods are overridable hence dynamically
dispatched by default. Use the `final` keyword or inferred `final` to
make them final and statically dispatched, just like instance
properties and methods.
3. Type properties can be stored or calculated, just like instance properties.

As you can see, it is a very simple and elegant design:

* Just a single keyword `type` to differentiate type member
declarations from instance member declarations. `type` is a good
keyword because:

  1. It is consistent with the wording of the concepts of `type
properties` and `type methods`.
  2. It is never used as a keyword before in Swift, Objective-C or
C. There will be no conflicts or overloading of it meanings.
* Except for that, how things are declared, differentiated and
optimized are exactly the same in both type and instance world. Very
consistent.

## Comparison with current design

* Dynamic Dispatch VS. Static Dispatch

// Old
class Foo {
  func dynamicInstanceMethod() {}
  final func staticInstanceMethod() {}

  class func dynamicTypeMethod() {}
  static func staticTypeMethod() {}
}
// New
class Foo {
  func dynamicInstanceMethod() {}
  final func staticInstanceMethod() {}

  type func dynamicTypeMethod() {}
  final type func staticTypeMethod() {}
}

* Stored Properties VS. Calculated Properties

// Old
class Bar {
  static let i = 1

  class var j: Int {
      return 1
  }
}
// New
class Bar {
  type let i = 1

  type var j: Int {
      return 1
  }
}

* Struct Implementation VS. Class Implementation of Protocol

// Old
protocol P {
  static func foo()
}

struct S: P {
  static func foo() {}
}

class C: P {
  class func foo() {}
}
// New
protocol P {
  type func foo()
}

struct S: P {
  type func foo() {}
}

class C: P {
  type func foo() {}
}

## Impact on existing code

With the help of a good migration tool, there will be no impact on
existing code at all. And the migration rules are very clear and
simple:

* Map `static` to `type` in protocols.
* Map `static` to `type` in structs and enums.
* Map `class` to `type` and `static` to `final type` in classes.

One concern I can think of is: because type methods are dynamically
dispatched by default in the new design, will we forget to do the
`final` optimization so the general performance of Swift code become
worse?

I think it is probably true. But we also forget to do the `final`
optimization for instance methods from time to time. Since there are
way more instance methods than type methods in most code the
performance impact will be very small. Maybe this change is a good
opportunity to remind us to do the `final` optimization for instance
methods thus even results in a better general performance.

And don’t forget we have the tools to automatically infer `final` for
us in many cases if we write the proper code and use the proper
compiler features.

After all, it is mainly on us to write good code to produce good final
products. If the system is consistent we’ll have better chances to
master it and use it properly.

## Alternatives considered

Alternatively we could:
* Keep using `static` and `class` keywords.
* Keep the confusion when implementing `static` protocol requirements
using `class` properties and methods in conforming classes.
* Keep the inconsistency between type member declarations and instance
member declarations.
* Keep overloading meanings on the `static` keyword that is already
historically overloaded in C and Objective-C with which Swift must mix
and match.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Chéyo Jiménez) #3

ChrisLattner wrote:

We considered unifying the syntax (e.g. using "type" as the keyword), but
that doesn't actually simply things. The keywords "class" and "static" are
good for familiarity and are quite descriptive (once you understand how +
methods work), and open the door for potentially adding truly static
methods to classes. The primary weirdness of this model is that protocols
have to pick a keyword (and we chose "class"), but on balance it is the
right tradeoff.

-Chris

Jul 5, 2014

https://devforums.apple.com/message/998365#998365

···

On Monday, December 7, 2015, an0 via swift-evolution < swift-evolution@swift.org> wrote:

The idea is simple but the reasoning is long. So please bear with me.
You can read on github for a better reading experience:

https://github.com/an0/swift-evolution/blob/master/proposals/NNNN-unify-static-and-class-keywords.md
.

## Introduction

The coexistence of `static` and `class` keywords for declaring type
properties and methods is confusing and causes inconsistency between
type and instance member declarations. This document reasons why we
don’t need both and suggests we unify them with a better keyword
`type`.

## Motivation

### Confusion

One “language enhancement” of [Swift
1.2](
https://developer.apple.com/library/ios/releasenotes/DeveloperTools/RN-Xcode/Chapters/xc6_release_notes.html#//apple_ref/doc/uid/TP40001051-CH4-SW6
)
is:
> “static” methods and properties are now allowed in classes (as an alias
for class final). You are now allowed to declare static stored properties
in classes, which have global storage and are lazily initialized on first
access (like global variables). Protocols now declare type requirements as
static requirements instead of declaring them as class requirements.
(17198298)

If even the Swift team itself has difficulties in picking one from the
two and had to revert its initial decision after several revisions, we
know these keywords are indeed confusing.

So now protocols use `static` to declare type methods, when a class
adapts such protocols, should it implement those static methods, as
static methods or class methods?

But static means final, right? Does it mean we can not override these
methods in subclasses of the conforming class?

These kinds of unnecessary confusion and hesitation should be
resolved, and could if this proposal is implemented.

### Unnecessary and inconsistent differentiation

The `class` keyword is only used in classes. In the current
implementation of Swift the differences between `class` and `static`
are:

1. Class properties can only be calculated properties but not stored
properties.
2. Class methods(also calculated properties) are dynamically
dispatched while static ones are statically dispatched.

If we can eliminate the differences or find better ways to
differentiate we can use one unified keyword instead for declaring
type properties and methods.

Let’s see.

#### Class stored properties VS. static stored properties

If you use the `class` keyword to declare a stored property in a class
you will get this compiling error:
> class stored properties not yet supported in classes; did you mean
'static'?

So what are class stored properties? How are they different from
static stored properties?

As far as I know, class stored properties, if ever implemented in
Swift, “would be what Ruby calls ‘class instance
variables’”.<sup>[1](
https://twitter.com/UINT_MIN/status/584104757117095936)</sup>

So what are class instance variables?

The best explanation I can find is this
[one](http://martinfowler.com/bliki/ClassInstanceVariable.html) from
Martin Fowler.

Do we really want this feature in Swift? “If we didn't already have
these, would we add them to Swift 3?"

I strongly believe we won’t add it to Swift 3. Actually I believe we
will never add it to Swift, because its use cases are so rare which is
also why it hasn’t been implemented so far in Swift.

If we agree we are not going to support class stored properties, there
is and will be only one kind of stored properties for types and we
only need one keyword to declare such properties.

#### Class methods VS. static methods

*Since calculated properties are also methods in essence they are also
covered by this section.*

The only difference is how methods are dispatched.

Let’s see [how we handle it for instance
methods](https://developer.apple.com/swift/blog/?id=27):

* Methods are overridable hence dynamically dispatched by default.
* In performance critical code use these techniques to restrict this
dynamic behavior when it isn’t needed to improve performance:

    1. Use the `final` keyword when we know that a declaration does
not need to be overridden.
    2. Infer `final` on declarations referenced in one file by
applying the `private` keyword.
    3. Use `Whole Module Optimization` to infer `final` on `internal`
declarations.

So why abandon this whole system to use another totally different one
for differentiating `static dispatch` and `dynamic dispatch` for type
methods?

If we reuse this system for type methods, not only can we have a
consistent design for both instance and type methods, but also we can
get rid of the last place where two keywords for type member
declarations are needed.

## Proposed solution

1. Use the keyword `type` to declare type properties and methods.
2. Type properties and methods are overridable hence dynamically
dispatched by default. Use the `final` keyword or inferred `final` to
make them final and statically dispatched, just like instance
properties and methods.
3. Type properties can be stored or calculated, just like instance
properties.

As you can see, it is a very simple and elegant design:

* Just a single keyword `type` to differentiate type member
declarations from instance member declarations. `type` is a good
keyword because:

    1. It is consistent with the wording of the concepts of `type
properties` and `type methods`.
    2. It is never used as a keyword before in Swift, Objective-C or
C. There will be no conflicts or overloading of it meanings.
* Except for that, how things are declared, differentiated and
optimized are exactly the same in both type and instance world. Very
consistent.

## Comparison with current design

* Dynamic Dispatch VS. Static Dispatch

// Old
class Foo {
    func dynamicInstanceMethod() {}
    final func staticInstanceMethod() {}

    class func dynamicTypeMethod() {}
    static func staticTypeMethod() {}
}
// New
class Foo {
    func dynamicInstanceMethod() {}
    final func staticInstanceMethod() {}

    type func dynamicTypeMethod() {}
    final type func staticTypeMethod() {}
}

* Stored Properties VS. Calculated Properties

// Old
class Bar {
    static let i = 1

    class var j: Int {
        return 1
    }
}
// New
class Bar {
    type let i = 1

    type var j: Int {
        return 1
    }
}

* Struct Implementation VS. Class Implementation of Protocol

// Old
protocol P {
    static func foo()
}

struct S: P {
    static func foo() {}
}

class C: P {
    class func foo() {}
}
// New
protocol P {
    type func foo()
}

struct S: P {
    type func foo() {}
}

class C: P {
    type func foo() {}
}

## Impact on existing code

With the help of a good migration tool, there will be no impact on
existing code at all. And the migration rules are very clear and
simple:

* Map `static` to `type` in protocols.
* Map `static` to `type` in structs and enums.
* Map `class` to `type` and `static` to `final type` in classes.

One concern I can think of is: because type methods are dynamically
dispatched by default in the new design, will we forget to do the
`final` optimization so the general performance of Swift code become
worse?

I think it is probably true. But we also forget to do the `final`
optimization for instance methods from time to time. Since there are
way more instance methods than type methods in most code the
performance impact will be very small. Maybe this change is a good
opportunity to remind us to do the `final` optimization for instance
methods thus even results in a better general performance.

And don’t forget we have the tools to automatically infer `final` for
us in many cases if we write the proper code and use the proper
compiler features.

After all, it is mainly on us to write good code to produce good final
products. If the system is consistent we’ll have better chances to
master it and use it properly.

## Alternatives considered

Alternatively we could:
* Keep using `static` and `class` keywords.
* Keep the confusion when implementing `static` protocol requirements
using `class` properties and methods in conforming classes.
* Keep the inconsistency between type member declarations and instance
member declarations.
* Keep overloading meanings on the `static` keyword that is already
historically overloaded in C and Objective-C with which Swift must mix
and match.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <javascript:;>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Chris Lattner) #4

The coexistence of `static` and `class` keywords for declaring type
properties and methods is confusing and causes inconsistency between
type and instance member declarations. This document reasons why we
don’t need both and suggests we unify them with a better keyword
`type`.

I’m sure you know this, but for folks who haven’t dug through the history, the design team has already implemented, evaluated and rejected this idea. We have also spent a lot of time over the years discussing and debating the issue, and have come to the current approach. Since the Swift 1.2 changes went in, we haven’t seen significant confusion.

#### Class stored properties VS. static stored properties

If you use the `class` keyword to declare a stored property in a class
you will get this compiling error:

class stored properties not yet supported in classes; did you mean 'static'?

So what are class stored properties? How are they different from
static stored properties?

This is a well-defined concept that comes from the Objective-C language, where class methods are dynamically dispatched. We are not willing to sacrifice compatibility with this concept. Similarly, we need and want “static” methods in classes for the common case in which dynamic dispatch is not desired.

Further, the current Swift design works well for folks more familiar with Java or C++ object models can just ignore class methods and use static methods. They behave pretty much as they would expect.

Class stored properties VS. static stored properties

You list many complaints about class properties, then go on to suggest that we replace “class” with “type”. It seems that your complaints aren’t actually relevant to the proposal, since you’re not actually removing them from the model. In fact, instead of “static var x” you’d have to write “final type var x”, which would be an unfortunate regression.

## Proposed solution: type.

This sacrifices all familiarity for folks coming from other extended C-family of languages, is not precedented in a popular language that I’m aware of, and is an unfortunate word to take as a keyword.

Beyond that, what you’re attempting to address is pretty much a non-problem. I’m aware of a lot of problems with Swift :-) but I have never seen the Swift 1.2+ design cause practical problems.

-Chris

···

On Dec 7, 2015, at 8:13 AM, an0 via swift-evolution <swift-evolution@swift.org> wrote:


(Matthew Johnson) #5

I think unifying these keywords would make a lot of sense, but neither would really be suitable as the unified choice. 'class' would be out of place in structs and enums. 'static' would be out of place for members that can be overridden in a class.

If we do unify this keyword, I believe combining it with 'final' in a class would recover the behavior we currently get when using 'static' in a class. (If this is not correct I would want to know how we achieve that behavior with the unified keyword)

There are a lot of drawbacks to using 'type' and I think we should find something better.

···

Sent from my iPad

On Dec 7, 2015, at 12:11 PM, Ling Wang via swift-evolution <swift-evolution@swift.org> wrote:

`type` is the best I can come up with so far. Using `type` to declare type members inside types is completely parallel with using `class` to declare class members inside classes, so conceptually it should be easy to accept. It may look a bit uncomfortable at first simply because it is new and different, especially to those with C++ and Java experiences.

On Dec 7, 2015, at 11:01 AM, David Hart <david@hartbit.com> wrote:

I really like this proposition, but I'm not a fan of the keyword, but can't think of anything better right now...

On 07 Dec 2015, at 17:13, an0 via swift-evolution <swift-evolution@swift.org> wrote:

The idea is simple but the reasoning is long. So please bear with me.
You can read on github for a better reading experience:
https://github.com/an0/swift-evolution/blob/master/proposals/NNNN-unify-static-and-class-keywords.md.

## Introduction

The coexistence of `static` and `class` keywords for declaring type
properties and methods is confusing and causes inconsistency between
type and instance member declarations. This document reasons why we
don’t need both and suggests we unify them with a better keyword
`type`.

## Motivation

### Confusion

One “language enhancement” of [Swift
1.2](https://developer.apple.com/library/ios/releasenotes/DeveloperTools/RN-Xcode/Chapters/xc6_release_notes.html#//apple_ref/doc/uid/TP40001051-CH4-SW6)
is:

“static” methods and properties are now allowed in classes (as an alias for class final). You are now allowed to declare static stored properties in classes, which have global storage and are lazily initialized on first access (like global variables). Protocols now declare type requirements as static requirements instead of declaring them as class requirements. (17198298)

If even the Swift team itself has difficulties in picking one from the
two and had to revert its initial decision after several revisions, we
know these keywords are indeed confusing.

So now protocols use `static` to declare type methods, when a class
adapts such protocols, should it implement those static methods, as
static methods or class methods?

But static means final, right? Does it mean we can not override these
methods in subclasses of the conforming class?

These kinds of unnecessary confusion and hesitation should be
resolved, and could if this proposal is implemented.

### Unnecessary and inconsistent differentiation

The `class` keyword is only used in classes. In the current
implementation of Swift the differences between `class` and `static`
are:

1. Class properties can only be calculated properties but not stored properties.
2. Class methods(also calculated properties) are dynamically
dispatched while static ones are statically dispatched.

If we can eliminate the differences or find better ways to
differentiate we can use one unified keyword instead for declaring
type properties and methods.

Let’s see.

#### Class stored properties VS. static stored properties

If you use the `class` keyword to declare a stored property in a class
you will get this compiling error:

class stored properties not yet supported in classes; did you mean 'static'?

So what are class stored properties? How are they different from
static stored properties?

As far as I know, class stored properties, if ever implemented in
Swift, “would be what Ruby calls ‘class instance
variables’”.<sup>[1](https://twitter.com/UINT_MIN/status/584104757117095936)</sup>

So what are class instance variables?

The best explanation I can find is this
[one](http://martinfowler.com/bliki/ClassInstanceVariable.html) from
Martin Fowler.

Do we really want this feature in Swift? “If we didn't already have
these, would we add them to Swift 3?"

I strongly believe we won’t add it to Swift 3. Actually I believe we
will never add it to Swift, because its use cases are so rare which is
also why it hasn’t been implemented so far in Swift.

If we agree we are not going to support class stored properties, there
is and will be only one kind of stored properties for types and we
only need one keyword to declare such properties.

#### Class methods VS. static methods

*Since calculated properties are also methods in essence they are also
covered by this section.*

The only difference is how methods are dispatched.

Let’s see [how we handle it for instance
methods](https://developer.apple.com/swift/blog/?id=27):

* Methods are overridable hence dynamically dispatched by default.
* In performance critical code use these techniques to restrict this
dynamic behavior when it isn’t needed to improve performance:

1. Use the `final` keyword when we know that a declaration does
not need to be overridden.
2. Infer `final` on declarations referenced in one file by
applying the `private` keyword.
3. Use `Whole Module Optimization` to infer `final` on `internal`
declarations.

So why abandon this whole system to use another totally different one
for differentiating `static dispatch` and `dynamic dispatch` for type
methods?

If we reuse this system for type methods, not only can we have a
consistent design for both instance and type methods, but also we can
get rid of the last place where two keywords for type member
declarations are needed.

## Proposed solution

1. Use the keyword `type` to declare type properties and methods.
2. Type properties and methods are overridable hence dynamically
dispatched by default. Use the `final` keyword or inferred `final` to
make them final and statically dispatched, just like instance
properties and methods.
3. Type properties can be stored or calculated, just like instance properties.

As you can see, it is a very simple and elegant design:

* Just a single keyword `type` to differentiate type member
declarations from instance member declarations. `type` is a good
keyword because:

1. It is consistent with the wording of the concepts of `type
properties` and `type methods`.
2. It is never used as a keyword before in Swift, Objective-C or
C. There will be no conflicts or overloading of it meanings.
* Except for that, how things are declared, differentiated and
optimized are exactly the same in both type and instance world. Very
consistent.

## Comparison with current design

* Dynamic Dispatch VS. Static Dispatch

// Old
class Foo {
 func dynamicInstanceMethod() {}
 final func staticInstanceMethod() {}

 class func dynamicTypeMethod() {}
 static func staticTypeMethod() {}
}
// New
class Foo {
 func dynamicInstanceMethod() {}
 final func staticInstanceMethod() {}

 type func dynamicTypeMethod() {}
 final type func staticTypeMethod() {}
}

* Stored Properties VS. Calculated Properties

// Old
class Bar {
 static let i = 1

 class var j: Int {
     return 1
 }
}
// New
class Bar {
 type let i = 1

 type var j: Int {
     return 1
 }
}

* Struct Implementation VS. Class Implementation of Protocol

// Old
protocol P {
 static func foo()
}

struct S: P {
 static func foo() {}
}

class C: P {
 class func foo() {}
}
// New
protocol P {
 type func foo()
}

struct S: P {
 type func foo() {}
}

class C: P {
 type func foo() {}
}

## Impact on existing code

With the help of a good migration tool, there will be no impact on
existing code at all. And the migration rules are very clear and
simple:

* Map `static` to `type` in protocols.
* Map `static` to `type` in structs and enums.
* Map `class` to `type` and `static` to `final type` in classes.

One concern I can think of is: because type methods are dynamically
dispatched by default in the new design, will we forget to do the
`final` optimization so the general performance of Swift code become
worse?

I think it is probably true. But we also forget to do the `final`
optimization for instance methods from time to time. Since there are
way more instance methods than type methods in most code the
performance impact will be very small. Maybe this change is a good
opportunity to remind us to do the `final` optimization for instance
methods thus even results in a better general performance.

And don’t forget we have the tools to automatically infer `final` for
us in many cases if we write the proper code and use the proper
compiler features.

After all, it is mainly on us to write good code to produce good final
products. If the system is consistent we’ll have better chances to
master it and use it properly.

## Alternatives considered

Alternatively we could:
* Keep using `static` and `class` keywords.
* Keep the confusion when implementing `static` protocol requirements
using `class` properties and methods in conforming classes.
* Keep the inconsistency between type member declarations and instance
member declarations.
* Keep overloading meanings on the `static` keyword that is already
historically overloaded in C and Objective-C with which Swift must mix
and match.
_______________________________________________
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


(Ling Wang) #6

The coexistence of `static` and `class` keywords for declaring type
properties and methods is confusing and causes inconsistency between
type and instance member declarations. This document reasons why we
don’t need both and suggests we unify them with a better keyword
`type`.

I’m sure you know this, but for folks who haven’t dug through the history, the design team has already implemented, evaluated and rejected this idea. We have also spent a lot of time over the years discussing and debating the issue, and have come to the current approach. Since the Swift 1.2 changes went in, we haven’t seen significant confusion.

#### Class stored properties VS. static stored properties

If you use the `class` keyword to declare a stored property in a class
you will get this compiling error:

class stored properties not yet supported in classes; did you mean 'static'?

So what are class stored properties? How are they different from
static stored properties?

This is a well-defined concept that comes from the Objective-C language, where class methods are dynamically dispatched. We are not willing to sacrifice compatibility with this concept.

I didn’t say anything against "class methods are dynamically dispatched”. Actually my proposal states that type methods are dynamically dispatched by default.

Similarly, we need and want “static” methods in classes for the common case in which dynamic dispatch is not desired.

I know it is for performance optimization. But why not use `final`? Also, did you read my optimization concern in this part: https://github.com/an0/swift-evolution/blob/master/proposals/NNNN-unify-static-and-class-keywords.md#impact-on-existing-code? <https://github.com/an0/swift-evolution/blob/master/proposals/NNNN-unify-static-and-class-keywords.md#impact-on-existing-code?> How do we enforce “static” dispatching for instance methods that are way more than type methods in most code?

Further, the current Swift design works well for folks more familiar with Java or C++ object models can just ignore class methods and use static methods. They behave pretty much as they would expect.

Did you read the part about inconsistency between type and instance member declarations(https://github.com/an0/swift-evolution/blob/master/proposals/NNNN-unify-static-and-class-keywords.md#class-methods-vs-static-methods) <https://github.com/an0/swift-evolution/blob/master/proposals/NNNN-unify-static-and-class-keywords.md#class-methods-vs-static-methods?>? What do you think about it? Do you think compatibilities with other older languages are more important than the consistencies within Swift itself?

Class stored properties VS. static stored properties

You list many complaints about class properties, then go on to suggest that we replace “class” with “type”. It seems that your complaints aren’t actually relevant to the proposal, since you’re not actually removing them from the model. In fact, instead of “static var x” you’d have to write “final type var x”, which would be an unfortunate regression.

When you said "You list many complaints about class properties” you meant “class stored properties”, right?

If so I don’t think I’ve ever complained about it because Swift doesn’t support class stored properties yet. My points about class stored properties are:
1. Are they useful enough? Do we want it in Swift?
2. Are we going to add it in Swift? If yes, when?
3. If no, then we only have one kind of type stored properties, why do we need two keywords for them?

## Proposed solution: type.

This sacrifices all familiarity for folks coming from other extended C-family of languages, is not precedented in a popular language that I’m aware of, and is an unfortunate word to take as a keyword.

As said above, I think consistencies within Swift itself are more important than compatibilities and familiarity with other languages.

Beyond that, what you’re attempting to address is pretty much a non-problem. I’m aware of a lot of problems with Swift :slight_smile: but I have never seen the Swift 1.2+ design cause practical problems.

I know there are a lot other problems that are more urgent than what we are talking about here. But I can’t agree that the inconsistency I mentioned in this proposal is a non-problem.

···

On Dec 7, 2015, at 6:21 PM, Chris Lattner <clattner@apple.com> wrote:
On Dec 7, 2015, at 8:13 AM, an0 via swift-evolution <swift-evolution@swift.org> wrote:

-Chris


(David Hart) #7

The big problem with 'type' is that it's often used as an identifier for variables and properties.

···

On 07 Dec 2015, at 19:11, Ling Wang <an00na@gmail.com> wrote:

`type` is the best I can come up with so far. Using `type` to declare type members inside types is completely parallel with using `class` to declare class members inside classes, so conceptually it should be easy to accept. It may look a bit uncomfortable at first simply because it is new and different, especially to those with C++ and Java experiences.

On Dec 7, 2015, at 11:01 AM, David Hart <david@hartbit.com> wrote:

I really like this proposition, but I'm not a fan of the keyword, but can't think of anything better right now...

On 07 Dec 2015, at 17:13, an0 via swift-evolution <swift-evolution@swift.org> wrote:

The idea is simple but the reasoning is long. So please bear with me.
You can read on github for a better reading experience:
https://github.com/an0/swift-evolution/blob/master/proposals/NNNN-unify-static-and-class-keywords.md.

## Introduction

The coexistence of `static` and `class` keywords for declaring type
properties and methods is confusing and causes inconsistency between
type and instance member declarations. This document reasons why we
don’t need both and suggests we unify them with a better keyword
`type`.

## Motivation

### Confusion

One “language enhancement” of [Swift
1.2](https://developer.apple.com/library/ios/releasenotes/DeveloperTools/RN-Xcode/Chapters/xc6_release_notes.html#//apple_ref/doc/uid/TP40001051-CH4-SW6)
is:

“static” methods and properties are now allowed in classes (as an alias for class final). You are now allowed to declare static stored properties in classes, which have global storage and are lazily initialized on first access (like global variables). Protocols now declare type requirements as static requirements instead of declaring them as class requirements. (17198298)

If even the Swift team itself has difficulties in picking one from the
two and had to revert its initial decision after several revisions, we
know these keywords are indeed confusing.

So now protocols use `static` to declare type methods, when a class
adapts such protocols, should it implement those static methods, as
static methods or class methods?

But static means final, right? Does it mean we can not override these
methods in subclasses of the conforming class?

These kinds of unnecessary confusion and hesitation should be
resolved, and could if this proposal is implemented.

### Unnecessary and inconsistent differentiation

The `class` keyword is only used in classes. In the current
implementation of Swift the differences between `class` and `static`
are:

1. Class properties can only be calculated properties but not stored properties.
2. Class methods(also calculated properties) are dynamically
dispatched while static ones are statically dispatched.

If we can eliminate the differences or find better ways to
differentiate we can use one unified keyword instead for declaring
type properties and methods.

Let’s see.

#### Class stored properties VS. static stored properties

If you use the `class` keyword to declare a stored property in a class
you will get this compiling error:

class stored properties not yet supported in classes; did you mean 'static'?

So what are class stored properties? How are they different from
static stored properties?

As far as I know, class stored properties, if ever implemented in
Swift, “would be what Ruby calls ‘class instance
variables’”.<sup>[1](https://twitter.com/UINT_MIN/status/584104757117095936)</sup>

So what are class instance variables?

The best explanation I can find is this
[one](http://martinfowler.com/bliki/ClassInstanceVariable.html) from
Martin Fowler.

Do we really want this feature in Swift? “If we didn't already have
these, would we add them to Swift 3?"

I strongly believe we won’t add it to Swift 3. Actually I believe we
will never add it to Swift, because its use cases are so rare which is
also why it hasn’t been implemented so far in Swift.

If we agree we are not going to support class stored properties, there
is and will be only one kind of stored properties for types and we
only need one keyword to declare such properties.

#### Class methods VS. static methods

*Since calculated properties are also methods in essence they are also
covered by this section.*

The only difference is how methods are dispatched.

Let’s see [how we handle it for instance
methods](https://developer.apple.com/swift/blog/?id=27):

* Methods are overridable hence dynamically dispatched by default.
* In performance critical code use these techniques to restrict this
dynamic behavior when it isn’t needed to improve performance:

1. Use the `final` keyword when we know that a declaration does
not need to be overridden.
2. Infer `final` on declarations referenced in one file by
applying the `private` keyword.
3. Use `Whole Module Optimization` to infer `final` on `internal`
declarations.

So why abandon this whole system to use another totally different one
for differentiating `static dispatch` and `dynamic dispatch` for type
methods?

If we reuse this system for type methods, not only can we have a
consistent design for both instance and type methods, but also we can
get rid of the last place where two keywords for type member
declarations are needed.

## Proposed solution

1. Use the keyword `type` to declare type properties and methods.
2. Type properties and methods are overridable hence dynamically
dispatched by default. Use the `final` keyword or inferred `final` to
make them final and statically dispatched, just like instance
properties and methods.
3. Type properties can be stored or calculated, just like instance properties.

As you can see, it is a very simple and elegant design:

* Just a single keyword `type` to differentiate type member
declarations from instance member declarations. `type` is a good
keyword because:

1. It is consistent with the wording of the concepts of `type
properties` and `type methods`.
2. It is never used as a keyword before in Swift, Objective-C or
C. There will be no conflicts or overloading of it meanings.
* Except for that, how things are declared, differentiated and
optimized are exactly the same in both type and instance world. Very
consistent.

## Comparison with current design

* Dynamic Dispatch VS. Static Dispatch

// Old
class Foo {
 func dynamicInstanceMethod() {}
 final func staticInstanceMethod() {}

 class func dynamicTypeMethod() {}
 static func staticTypeMethod() {}
}
// New
class Foo {
 func dynamicInstanceMethod() {}
 final func staticInstanceMethod() {}

 type func dynamicTypeMethod() {}
 final type func staticTypeMethod() {}
}

* Stored Properties VS. Calculated Properties

// Old
class Bar {
 static let i = 1

 class var j: Int {
     return 1
 }
}
// New
class Bar {
 type let i = 1

 type var j: Int {
     return 1
 }
}

* Struct Implementation VS. Class Implementation of Protocol

// Old
protocol P {
 static func foo()
}

struct S: P {
 static func foo() {}
}

class C: P {
 class func foo() {}
}
// New
protocol P {
 type func foo()
}

struct S: P {
 type func foo() {}
}

class C: P {
 type func foo() {}
}

## Impact on existing code

With the help of a good migration tool, there will be no impact on
existing code at all. And the migration rules are very clear and
simple:

* Map `static` to `type` in protocols.
* Map `static` to `type` in structs and enums.
* Map `class` to `type` and `static` to `final type` in classes.

One concern I can think of is: because type methods are dynamically
dispatched by default in the new design, will we forget to do the
`final` optimization so the general performance of Swift code become
worse?

I think it is probably true. But we also forget to do the `final`
optimization for instance methods from time to time. Since there are
way more instance methods than type methods in most code the
performance impact will be very small. Maybe this change is a good
opportunity to remind us to do the `final` optimization for instance
methods thus even results in a better general performance.

And don’t forget we have the tools to automatically infer `final` for
us in many cases if we write the proper code and use the proper
compiler features.

After all, it is mainly on us to write good code to produce good final
products. If the system is consistent we’ll have better chances to
master it and use it properly.

## Alternatives considered

Alternatively we could:
* Keep using `static` and `class` keywords.
* Keep the confusion when implementing `static` protocol requirements
using `class` properties and methods in conforming classes.
* Keep the inconsistency between type member declarations and instance
member declarations.
* Keep overloading meanings on the `static` keyword that is already
historically overloaded in C and Objective-C with which Swift must mix
and match.
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Ling Wang) #8

I read that. But that's a long time ago, Swift has evolved a lot since
then. I believe the Swift team may have some new ideas about it or at least
could take a look at the ideas in this proposal.

Do you have any ideas of your own about this proposal? I'd really like to
learn:)

···

On Mon, Dec 7, 2015 at 12:49 PM J. Cheyo Jimenez <cheyo@masters3d.com> wrote:

ChrisLattner wrote:

We considered unifying the syntax (e.g. using "type" as the keyword), but
that doesn't actually simply things. The keywords "class" and "static" are
good for familiarity and are quite descriptive (once you understand how +
methods work), and open the door for potentially adding truly static
methods to classes. The primary weirdness of this model is that protocols
have to pick a keyword (and we chose "class"), but on balance it is the
right tradeoff.

-Chris

Jul 5, 2014

https://devforums.apple.com/message/998365#998365

On Monday, December 7, 2015, an0 via swift-evolution < > swift-evolution@swift.org> wrote:

The idea is simple but the reasoning is long. So please bear with me.
You can read on github for a better reading experience:

https://github.com/an0/swift-evolution/blob/master/proposals/NNNN-unify-static-and-class-keywords.md
.

## Introduction

The coexistence of `static` and `class` keywords for declaring type
properties and methods is confusing and causes inconsistency between
type and instance member declarations. This document reasons why we
don’t need both and suggests we unify them with a better keyword
`type`.

## Motivation

### Confusion

One “language enhancement” of [Swift
1.2](
https://developer.apple.com/library/ios/releasenotes/DeveloperTools/RN-Xcode/Chapters/xc6_release_notes.html#//apple_ref/doc/uid/TP40001051-CH4-SW6
)
is:
> “static” methods and properties are now allowed in classes (as an alias
for class final). You are now allowed to declare static stored properties
in classes, which have global storage and are lazily initialized on first
access (like global variables). Protocols now declare type requirements as
static requirements instead of declaring them as class requirements.
(17198298)

If even the Swift team itself has difficulties in picking one from the
two and had to revert its initial decision after several revisions, we
know these keywords are indeed confusing.

So now protocols use `static` to declare type methods, when a class
adapts such protocols, should it implement those static methods, as
static methods or class methods?

But static means final, right? Does it mean we can not override these
methods in subclasses of the conforming class?

These kinds of unnecessary confusion and hesitation should be
resolved, and could if this proposal is implemented.

### Unnecessary and inconsistent differentiation

The `class` keyword is only used in classes. In the current
implementation of Swift the differences between `class` and `static`
are:

1. Class properties can only be calculated properties but not stored
properties.
2. Class methods(also calculated properties) are dynamically
dispatched while static ones are statically dispatched.

If we can eliminate the differences or find better ways to
differentiate we can use one unified keyword instead for declaring
type properties and methods.

Let’s see.

#### Class stored properties VS. static stored properties

If you use the `class` keyword to declare a stored property in a class
you will get this compiling error:
> class stored properties not yet supported in classes; did you mean
'static'?

So what are class stored properties? How are they different from
static stored properties?

As far as I know, class stored properties, if ever implemented in
Swift, “would be what Ruby calls ‘class instance
variables’”.<sup>[1](
https://twitter.com/UINT_MIN/status/584104757117095936)</sup>

So what are class instance variables?

The best explanation I can find is this
[one](http://martinfowler.com/bliki/ClassInstanceVariable.html) from
Martin Fowler.

Do we really want this feature in Swift? “If we didn't already have
these, would we add them to Swift 3?"

I strongly believe we won’t add it to Swift 3. Actually I believe we
will never add it to Swift, because its use cases are so rare which is
also why it hasn’t been implemented so far in Swift.

If we agree we are not going to support class stored properties, there
is and will be only one kind of stored properties for types and we
only need one keyword to declare such properties.

#### Class methods VS. static methods

*Since calculated properties are also methods in essence they are also
covered by this section.*

The only difference is how methods are dispatched.

Let’s see [how we handle it for instance
methods](https://developer.apple.com/swift/blog/?id=27):

* Methods are overridable hence dynamically dispatched by default.
* In performance critical code use these techniques to restrict this
dynamic behavior when it isn’t needed to improve performance:

    1. Use the `final` keyword when we know that a declaration does
not need to be overridden.
    2. Infer `final` on declarations referenced in one file by
applying the `private` keyword.
    3. Use `Whole Module Optimization` to infer `final` on `internal`
declarations.

So why abandon this whole system to use another totally different one
for differentiating `static dispatch` and `dynamic dispatch` for type
methods?

If we reuse this system for type methods, not only can we have a
consistent design for both instance and type methods, but also we can
get rid of the last place where two keywords for type member
declarations are needed.

## Proposed solution

1. Use the keyword `type` to declare type properties and methods.
2. Type properties and methods are overridable hence dynamically
dispatched by default. Use the `final` keyword or inferred `final` to
make them final and statically dispatched, just like instance
properties and methods.
3. Type properties can be stored or calculated, just like instance
properties.

As you can see, it is a very simple and elegant design:

* Just a single keyword `type` to differentiate type member
declarations from instance member declarations. `type` is a good
keyword because:

    1. It is consistent with the wording of the concepts of `type
properties` and `type methods`.
    2. It is never used as a keyword before in Swift, Objective-C or
C. There will be no conflicts or overloading of it meanings.
* Except for that, how things are declared, differentiated and
optimized are exactly the same in both type and instance world. Very
consistent.

## Comparison with current design

* Dynamic Dispatch VS. Static Dispatch

// Old
class Foo {
    func dynamicInstanceMethod() {}
    final func staticInstanceMethod() {}

    class func dynamicTypeMethod() {}
    static func staticTypeMethod() {}
}
// New
class Foo {
    func dynamicInstanceMethod() {}
    final func staticInstanceMethod() {}

    type func dynamicTypeMethod() {}
    final type func staticTypeMethod() {}
}

* Stored Properties VS. Calculated Properties

// Old
class Bar {
    static let i = 1

    class var j: Int {
        return 1
    }
}
// New
class Bar {
    type let i = 1

    type var j: Int {
        return 1
    }
}

* Struct Implementation VS. Class Implementation of Protocol

// Old
protocol P {
    static func foo()
}

struct S: P {
    static func foo() {}
}

class C: P {
    class func foo() {}
}
// New
protocol P {
    type func foo()
}

struct S: P {
    type func foo() {}
}

class C: P {
    type func foo() {}
}

## Impact on existing code

With the help of a good migration tool, there will be no impact on
existing code at all. And the migration rules are very clear and
simple:

* Map `static` to `type` in protocols.
* Map `static` to `type` in structs and enums.
* Map `class` to `type` and `static` to `final type` in classes.

One concern I can think of is: because type methods are dynamically
dispatched by default in the new design, will we forget to do the
`final` optimization so the general performance of Swift code become
worse?

I think it is probably true. But we also forget to do the `final`
optimization for instance methods from time to time. Since there are
way more instance methods than type methods in most code the
performance impact will be very small. Maybe this change is a good
opportunity to remind us to do the `final` optimization for instance
methods thus even results in a better general performance.

And don’t forget we have the tools to automatically infer `final` for
us in many cases if we write the proper code and use the proper
compiler features.

After all, it is mainly on us to write good code to produce good final
products. If the system is consistent we’ll have better chances to
master it and use it properly.

## Alternatives considered

Alternatively we could:
* Keep using `static` and `class` keywords.
* Keep the confusion when implementing `static` protocol requirements
using `class` properties and methods in conforming classes.
* Keep the inconsistency between type member declarations and instance
member declarations.
* Keep overloading meanings on the `static` keyword that is already
historically overloaded in C and Objective-C with which Swift must mix
and match.

_______________________________________________

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


(John McCall) #9

I think unifying these keywords would make a lot of sense, but neither would really be suitable as the unified choice. 'class' would be out of place in structs and enums. 'static' would be out of place for members that can be overridden in a class.

If we do unify this keyword, I believe combining it with 'final' in a class would recover the behavior we currently get when using 'static' in a class. (If this is not correct I would want to know how we achieve that behavior with the unified keyword)

There are a lot of drawbacks to using 'type' and I think we should find something better.

One important difference between “static” and “class” on a class is the behavior of storage. In principle, a static variable in a class is just a rescoped global (although it is unclear how this is affected by generics). A class variable in a class is conceptually a member of the class, and subclasses should get a separate copy.

John.

···

On Dec 7, 2015, at 10:56 AM, Matthew Johnson via swift-evolution <swift-evolution@swift.org> wrote:

Sent from my iPad

On Dec 7, 2015, at 12:11 PM, Ling Wang via swift-evolution <swift-evolution@swift.org> wrote:

`type` is the best I can come up with so far. Using `type` to declare type members inside types is completely parallel with using `class` to declare class members inside classes, so conceptually it should be easy to accept. It may look a bit uncomfortable at first simply because it is new and different, especially to those with C++ and Java experiences.

On Dec 7, 2015, at 11:01 AM, David Hart <david@hartbit.com> wrote:

I really like this proposition, but I'm not a fan of the keyword, but can't think of anything better right now...

On 07 Dec 2015, at 17:13, an0 via swift-evolution <swift-evolution@swift.org> wrote:

The idea is simple but the reasoning is long. So please bear with me.
You can read on github for a better reading experience:
https://github.com/an0/swift-evolution/blob/master/proposals/NNNN-unify-static-and-class-keywords.md.

## Introduction

The coexistence of `static` and `class` keywords for declaring type
properties and methods is confusing and causes inconsistency between
type and instance member declarations. This document reasons why we
don’t need both and suggests we unify them with a better keyword
`type`.

## Motivation

### Confusion

One “language enhancement” of [Swift
1.2](https://developer.apple.com/library/ios/releasenotes/DeveloperTools/RN-Xcode/Chapters/xc6_release_notes.html#//apple_ref/doc/uid/TP40001051-CH4-SW6)
is:

“static” methods and properties are now allowed in classes (as an alias for class final). You are now allowed to declare static stored properties in classes, which have global storage and are lazily initialized on first access (like global variables). Protocols now declare type requirements as static requirements instead of declaring them as class requirements. (17198298)

If even the Swift team itself has difficulties in picking one from the
two and had to revert its initial decision after several revisions, we
know these keywords are indeed confusing.

So now protocols use `static` to declare type methods, when a class
adapts such protocols, should it implement those static methods, as
static methods or class methods?

But static means final, right? Does it mean we can not override these
methods in subclasses of the conforming class?

These kinds of unnecessary confusion and hesitation should be
resolved, and could if this proposal is implemented.

### Unnecessary and inconsistent differentiation

The `class` keyword is only used in classes. In the current
implementation of Swift the differences between `class` and `static`
are:

1. Class properties can only be calculated properties but not stored properties.
2. Class methods(also calculated properties) are dynamically
dispatched while static ones are statically dispatched.

If we can eliminate the differences or find better ways to
differentiate we can use one unified keyword instead for declaring
type properties and methods.

Let’s see.

#### Class stored properties VS. static stored properties

If you use the `class` keyword to declare a stored property in a class
you will get this compiling error:

class stored properties not yet supported in classes; did you mean 'static'?

So what are class stored properties? How are they different from
static stored properties?

As far as I know, class stored properties, if ever implemented in
Swift, “would be what Ruby calls ‘class instance
variables’”.<sup>[1](https://twitter.com/UINT_MIN/status/584104757117095936)</sup>

So what are class instance variables?

The best explanation I can find is this
[one](http://martinfowler.com/bliki/ClassInstanceVariable.html) from
Martin Fowler.

Do we really want this feature in Swift? “If we didn't already have
these, would we add them to Swift 3?"

I strongly believe we won’t add it to Swift 3. Actually I believe we
will never add it to Swift, because its use cases are so rare which is
also why it hasn’t been implemented so far in Swift.

If we agree we are not going to support class stored properties, there
is and will be only one kind of stored properties for types and we
only need one keyword to declare such properties.

#### Class methods VS. static methods

*Since calculated properties are also methods in essence they are also
covered by this section.*

The only difference is how methods are dispatched.

Let’s see [how we handle it for instance
methods](https://developer.apple.com/swift/blog/?id=27):

* Methods are overridable hence dynamically dispatched by default.
* In performance critical code use these techniques to restrict this
dynamic behavior when it isn’t needed to improve performance:

1. Use the `final` keyword when we know that a declaration does
not need to be overridden.
2. Infer `final` on declarations referenced in one file by
applying the `private` keyword.
3. Use `Whole Module Optimization` to infer `final` on `internal`
declarations.

So why abandon this whole system to use another totally different one
for differentiating `static dispatch` and `dynamic dispatch` for type
methods?

If we reuse this system for type methods, not only can we have a
consistent design for both instance and type methods, but also we can
get rid of the last place where two keywords for type member
declarations are needed.

## Proposed solution

1. Use the keyword `type` to declare type properties and methods.
2. Type properties and methods are overridable hence dynamically
dispatched by default. Use the `final` keyword or inferred `final` to
make them final and statically dispatched, just like instance
properties and methods.
3. Type properties can be stored or calculated, just like instance properties.

As you can see, it is a very simple and elegant design:

* Just a single keyword `type` to differentiate type member
declarations from instance member declarations. `type` is a good
keyword because:

1. It is consistent with the wording of the concepts of `type
properties` and `type methods`.
2. It is never used as a keyword before in Swift, Objective-C or
C. There will be no conflicts or overloading of it meanings.
* Except for that, how things are declared, differentiated and
optimized are exactly the same in both type and instance world. Very
consistent.

## Comparison with current design

* Dynamic Dispatch VS. Static Dispatch

// Old
class Foo {
func dynamicInstanceMethod() {}
final func staticInstanceMethod() {}

class func dynamicTypeMethod() {}
static func staticTypeMethod() {}
}
// New
class Foo {
func dynamicInstanceMethod() {}
final func staticInstanceMethod() {}

type func dynamicTypeMethod() {}
final type func staticTypeMethod() {}
}

* Stored Properties VS. Calculated Properties

// Old
class Bar {
static let i = 1

class var j: Int {
    return 1
}
}
// New
class Bar {
type let i = 1

type var j: Int {
    return 1
}
}

* Struct Implementation VS. Class Implementation of Protocol

// Old
protocol P {
static func foo()
}

struct S: P {
static func foo() {}
}

class C: P {
class func foo() {}
}
// New
protocol P {
type func foo()
}

struct S: P {
type func foo() {}
}

class C: P {
type func foo() {}
}

## Impact on existing code

With the help of a good migration tool, there will be no impact on
existing code at all. And the migration rules are very clear and
simple:

* Map `static` to `type` in protocols.
* Map `static` to `type` in structs and enums.
* Map `class` to `type` and `static` to `final type` in classes.

One concern I can think of is: because type methods are dynamically
dispatched by default in the new design, will we forget to do the
`final` optimization so the general performance of Swift code become
worse?

I think it is probably true. But we also forget to do the `final`
optimization for instance methods from time to time. Since there are
way more instance methods than type methods in most code the
performance impact will be very small. Maybe this change is a good
opportunity to remind us to do the `final` optimization for instance
methods thus even results in a better general performance.

And don’t forget we have the tools to automatically infer `final` for
us in many cases if we write the proper code and use the proper
compiler features.

After all, it is mainly on us to write good code to produce good final
products. If the system is consistent we’ll have better chances to
master it and use it properly.

## Alternatives considered

Alternatively we could:
* Keep using `static` and `class` keywords.
* Keep the confusion when implementing `static` protocol requirements
using `class` properties and methods in conforming classes.
* Keep the inconsistency between type member declarations and instance
member declarations.
* Keep overloading meanings on the `static` keyword that is already
historically overloaded in C and Objective-C with which Swift must mix
and match.
_______________________________________________
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

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


(Matthew Johnson) #10

One important difference between “static” and “class” on a class is the behavior of storage. In principle, a static variable in a class is just a rescoped global (although it is unclear how this is affected by generics). A class variable in a class is conceptually a member of the class, and subclasses should get a separate copy.

I understand that this is the case in general, but is it still the case when a class variable is marked as final in its initial declaration?

If class variables do behave differently even when declared final I wonder whether the use cases for this behavior are compelling enough to justify the conceptual complexity of two different keywords. I would be very interested in seeing examples of using a final class variable where separate storage for each subclass is desirable and useful.


(Ling Wang) #11

I've already addressed that under "Class stored properties VS. static
stored properties"(https://github.com/an0/swift-evolution/blob/master/proposals/NNNN-unify-static-and-class-keywords.md#class-stored-properties-vs-static-stored-properties).
I don't think we'll add class stored properties to Swift though. It is
one of the premises of this proposal.

···

On Mon, Dec 7, 2015 at 1:22 PM, John McCall <rjmccall@apple.com> wrote:

On Dec 7, 2015, at 10:56 AM, Matthew Johnson via swift-evolution <swift-evolution@swift.org> wrote:

I think unifying these keywords would make a lot of sense, but neither would really be suitable as the unified choice. 'class' would be out of place in structs and enums. 'static' would be out of place for members that can be overridden in a class.

If we do unify this keyword, I believe combining it with 'final' in a class would recover the behavior we currently get when using 'static' in a class. (If this is not correct I would want to know how we achieve that behavior with the unified keyword)

There are a lot of drawbacks to using 'type' and I think we should find something better.

One important difference between “static” and “class” on a class is the behavior of storage. In principle, a static variable in a class is just a rescoped global (although it is unclear how this is affected by generics). A class variable in a class is conceptually a member of the class, and subclasses should get a separate copy.

John.

Sent from my iPad

On Dec 7, 2015, at 12:11 PM, Ling Wang via swift-evolution <swift-evolution@swift.org> wrote:

`type` is the best I can come up with so far. Using `type` to declare type members inside types is completely parallel with using `class` to declare class members inside classes, so conceptually it should be easy to accept. It may look a bit uncomfortable at first simply because it is new and different, especially to those with C++ and Java experiences.

On Dec 7, 2015, at 11:01 AM, David Hart <david@hartbit.com> wrote:

I really like this proposition, but I'm not a fan of the keyword, but can't think of anything better right now...

On 07 Dec 2015, at 17:13, an0 via swift-evolution <swift-evolution@swift.org> wrote:

The idea is simple but the reasoning is long. So please bear with me.
You can read on github for a better reading experience:
https://github.com/an0/swift-evolution/blob/master/proposals/NNNN-unify-static-and-class-keywords.md.

## Introduction

The coexistence of `static` and `class` keywords for declaring type
properties and methods is confusing and causes inconsistency between
type and instance member declarations. This document reasons why we
don’t need both and suggests we unify them with a better keyword
`type`.

## Motivation

### Confusion

One “language enhancement” of [Swift
1.2](https://developer.apple.com/library/ios/releasenotes/DeveloperTools/RN-Xcode/Chapters/xc6_release_notes.html#//apple_ref/doc/uid/TP40001051-CH4-SW6)
is:

“static” methods and properties are now allowed in classes (as an alias for class final). You are now allowed to declare static stored properties in classes, which have global storage and are lazily initialized on first access (like global variables). Protocols now declare type requirements as static requirements instead of declaring them as class requirements. (17198298)

If even the Swift team itself has difficulties in picking one from the
two and had to revert its initial decision after several revisions, we
know these keywords are indeed confusing.

So now protocols use `static` to declare type methods, when a class
adapts such protocols, should it implement those static methods, as
static methods or class methods?

But static means final, right? Does it mean we can not override these
methods in subclasses of the conforming class?

These kinds of unnecessary confusion and hesitation should be
resolved, and could if this proposal is implemented.

### Unnecessary and inconsistent differentiation

The `class` keyword is only used in classes. In the current
implementation of Swift the differences between `class` and `static`
are:

1. Class properties can only be calculated properties but not stored properties.
2. Class methods(also calculated properties) are dynamically
dispatched while static ones are statically dispatched.

If we can eliminate the differences or find better ways to
differentiate we can use one unified keyword instead for declaring
type properties and methods.

Let’s see.

#### Class stored properties VS. static stored properties

If you use the `class` keyword to declare a stored property in a class
you will get this compiling error:

class stored properties not yet supported in classes; did you mean 'static'?

So what are class stored properties? How are they different from
static stored properties?

As far as I know, class stored properties, if ever implemented in
Swift, “would be what Ruby calls ‘class instance
variables’”.<sup>[1](https://twitter.com/UINT_MIN/status/584104757117095936)</sup>

So what are class instance variables?

The best explanation I can find is this
[one](http://martinfowler.com/bliki/ClassInstanceVariable.html) from
Martin Fowler.

Do we really want this feature in Swift? “If we didn't already have
these, would we add them to Swift 3?"

I strongly believe we won’t add it to Swift 3. Actually I believe we
will never add it to Swift, because its use cases are so rare which is
also why it hasn’t been implemented so far in Swift.

If we agree we are not going to support class stored properties, there
is and will be only one kind of stored properties for types and we
only need one keyword to declare such properties.

#### Class methods VS. static methods

*Since calculated properties are also methods in essence they are also
covered by this section.*

The only difference is how methods are dispatched.

Let’s see [how we handle it for instance
methods](https://developer.apple.com/swift/blog/?id=27):

* Methods are overridable hence dynamically dispatched by default.
* In performance critical code use these techniques to restrict this
dynamic behavior when it isn’t needed to improve performance:

1. Use the `final` keyword when we know that a declaration does
not need to be overridden.
2. Infer `final` on declarations referenced in one file by
applying the `private` keyword.
3. Use `Whole Module Optimization` to infer `final` on `internal`
declarations.

So why abandon this whole system to use another totally different one
for differentiating `static dispatch` and `dynamic dispatch` for type
methods?

If we reuse this system for type methods, not only can we have a
consistent design for both instance and type methods, but also we can
get rid of the last place where two keywords for type member
declarations are needed.

## Proposed solution

1. Use the keyword `type` to declare type properties and methods.
2. Type properties and methods are overridable hence dynamically
dispatched by default. Use the `final` keyword or inferred `final` to
make them final and statically dispatched, just like instance
properties and methods.
3. Type properties can be stored or calculated, just like instance properties.

As you can see, it is a very simple and elegant design:

* Just a single keyword `type` to differentiate type member
declarations from instance member declarations. `type` is a good
keyword because:

1. It is consistent with the wording of the concepts of `type
properties` and `type methods`.
2. It is never used as a keyword before in Swift, Objective-C or
C. There will be no conflicts or overloading of it meanings.
* Except for that, how things are declared, differentiated and
optimized are exactly the same in both type and instance world. Very
consistent.

## Comparison with current design

* Dynamic Dispatch VS. Static Dispatch

// Old
class Foo {
func dynamicInstanceMethod() {}
final func staticInstanceMethod() {}

class func dynamicTypeMethod() {}
static func staticTypeMethod() {}
}
// New
class Foo {
func dynamicInstanceMethod() {}
final func staticInstanceMethod() {}

type func dynamicTypeMethod() {}
final type func staticTypeMethod() {}
}

* Stored Properties VS. Calculated Properties

// Old
class Bar {
static let i = 1

class var j: Int {
    return 1
}
}
// New
class Bar {
type let i = 1

type var j: Int {
    return 1
}
}

* Struct Implementation VS. Class Implementation of Protocol

// Old
protocol P {
static func foo()
}

struct S: P {
static func foo() {}
}

class C: P {
class func foo() {}
}
// New
protocol P {
type func foo()
}

struct S: P {
type func foo() {}
}

class C: P {
type func foo() {}
}

## Impact on existing code

With the help of a good migration tool, there will be no impact on
existing code at all. And the migration rules are very clear and
simple:

* Map `static` to `type` in protocols.
* Map `static` to `type` in structs and enums.
* Map `class` to `type` and `static` to `final type` in classes.

One concern I can think of is: because type methods are dynamically
dispatched by default in the new design, will we forget to do the
`final` optimization so the general performance of Swift code become
worse?

I think it is probably true. But we also forget to do the `final`
optimization for instance methods from time to time. Since there are
way more instance methods than type methods in most code the
performance impact will be very small. Maybe this change is a good
opportunity to remind us to do the `final` optimization for instance
methods thus even results in a better general performance.

And don’t forget we have the tools to automatically infer `final` for
us in many cases if we write the proper code and use the proper
compiler features.

After all, it is mainly on us to write good code to produce good final
products. If the system is consistent we’ll have better chances to
master it and use it properly.

## Alternatives considered

Alternatively we could:
* Keep using `static` and `class` keywords.
* Keep the confusion when implementing `static` protocol requirements
using `class` properties and methods in conforming classes.
* Keep the inconsistency between type member declarations and instance
member declarations.
* Keep overloading meanings on the `static` keyword that is already
historically overloaded in C and Objective-C with which Swift must mix
and match.
_______________________________________________
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

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

--
wangling.me


(Chris Lattner) #12

Class stored properties VS. static stored properties

You list many complaints about class properties, then go on to suggest that we replace “class” with “type”. It seems that your complaints aren’t actually relevant to the proposal, since you’re not actually removing them from the model. In fact, instead of “static var x” you’d have to write “final type var x”, which would be an unfortunate regression.

When you said "You list many complaints about class properties” you meant “class stored properties”, right?

If so I don’t think I’ve ever complained about it because Swift doesn’t support class stored properties yet. My points about class stored properties are:
1. Are they useful enough? Do we want it in Swift?
2. Are we going to add it in Swift? If yes, when?

Perhaps, but they are very low priority.

3. If no, then we only have one kind of type stored properties, why do we need two keywords for them?

You’re missing what I’m trying to say. With your design:

class Foo {
  type var x : Int
}

This would be a stored class property, which isn’t supported and won’t be for the forseeable. This would require people to write:

class Foo {
  final type var x : Int
}

This is a lot worse than:

class Foo {
  static var x : Int
}

... both in terms of boilerplate noise, but also in that it leads them down the wrong path. Many people would write “type var x : Int” wanting a static member, because they don’t understand how class variables work.

Your approach would make class members *more* prominent, not less. We’ve tried this, this is not a theoretical concern.

-Chris

···

On Dec 7, 2015, at 5:09 PM, Ling Wang <an00na@gmail.com> wrote:


(Ling Wang) #13

Do you mind explaining the drawbacks of using `type` so that maybe I can
think of a better one?

···

On Mon, Dec 7, 2015 at 12:56 PM Matthew Johnson <matthew@anandabits.com> wrote:

I think unifying these keywords would make a lot of sense, but neither
would really be suitable as the unified choice. 'class' would be out of
place in structs and enums. 'static' would be out of place for members
that can be overridden in a class.

If we do unify this keyword, I believe combining it with 'final' in a
class would recover the behavior we currently get when using 'static' in a
class. (If this is not correct I would want to know how we achieve that
behavior with the unified keyword)

There are a lot of drawbacks to using 'type' and I think we should find
something better.

Sent from my iPad

> On Dec 7, 2015, at 12:11 PM, Ling Wang via swift-evolution < > swift-evolution@swift.org> wrote:
>
> `type` is the best I can come up with so far. Using `type` to declare
type members inside types is completely parallel with using `class` to
declare class members inside classes, so conceptually it should be easy to
accept. It may look a bit uncomfortable at first simply because it is new
and different, especially to those with C++ and Java experiences.
>
>> On Dec 7, 2015, at 11:01 AM, David Hart <david@hartbit.com> wrote:
>>
>> I really like this proposition, but I'm not a fan of the keyword, but
can't think of anything better right now...
>>
>>> On 07 Dec 2015, at 17:13, an0 via swift-evolution < > swift-evolution@swift.org> wrote:
>>>
>>> The idea is simple but the reasoning is long. So please bear with me.
>>> You can read on github for a better reading experience:
>>>
https://github.com/an0/swift-evolution/blob/master/proposals/NNNN-unify-static-and-class-keywords.md
.
>>>
>>> ## Introduction
>>>
>>> The coexistence of `static` and `class` keywords for declaring type
>>> properties and methods is confusing and causes inconsistency between
>>> type and instance member declarations. This document reasons why we
>>> don’t need both and suggests we unify them with a better keyword
>>> `type`.
>>>
>>> ## Motivation
>>>
>>> ### Confusion
>>>
>>> One “language enhancement” of [Swift
>>> 1.2](
https://developer.apple.com/library/ios/releasenotes/DeveloperTools/RN-Xcode/Chapters/xc6_release_notes.html#//apple_ref/doc/uid/TP40001051-CH4-SW6
)
>>> is:
>>>> “static” methods and properties are now allowed in classes (as an
alias for class final). You are now allowed to declare static stored
properties in classes, which have global storage and are lazily initialized
on first access (like global variables). Protocols now declare type
requirements as static requirements instead of declaring them as class
requirements. (17198298)
>>>
>>> If even the Swift team itself has difficulties in picking one from the
>>> two and had to revert its initial decision after several revisions, we
>>> know these keywords are indeed confusing.
>>>
>>> So now protocols use `static` to declare type methods, when a class
>>> adapts such protocols, should it implement those static methods, as
>>> static methods or class methods?
>>>
>>> But static means final, right? Does it mean we can not override these
>>> methods in subclasses of the conforming class?
>>>
>>> These kinds of unnecessary confusion and hesitation should be
>>> resolved, and could if this proposal is implemented.
>>>
>>> ### Unnecessary and inconsistent differentiation
>>>
>>> The `class` keyword is only used in classes. In the current
>>> implementation of Swift the differences between `class` and `static`
>>> are:
>>>
>>> 1. Class properties can only be calculated properties but not stored
properties.
>>> 2. Class methods(also calculated properties) are dynamically
>>> dispatched while static ones are statically dispatched.
>>>
>>> If we can eliminate the differences or find better ways to
>>> differentiate we can use one unified keyword instead for declaring
>>> type properties and methods.
>>>
>>> Let’s see.
>>>
>>> #### Class stored properties VS. static stored properties
>>>
>>> If you use the `class` keyword to declare a stored property in a class
>>> you will get this compiling error:
>>>> class stored properties not yet supported in classes; did you mean
'static'?
>>>
>>> So what are class stored properties? How are they different from
>>> static stored properties?
>>>
>>> As far as I know, class stored properties, if ever implemented in
>>> Swift, “would be what Ruby calls ‘class instance
>>> variables’”.<sup>[1](
https://twitter.com/UINT_MIN/status/584104757117095936)</sup>
>>>
>>> So what are class instance variables?
>>>
>>> The best explanation I can find is this
>>> [one](http://martinfowler.com/bliki/ClassInstanceVariable.html) from
>>> Martin Fowler.
>>>
>>> Do we really want this feature in Swift? “If we didn't already have
>>> these, would we add them to Swift 3?"
>>>
>>> I strongly believe we won’t add it to Swift 3. Actually I believe we
>>> will never add it to Swift, because its use cases are so rare which is
>>> also why it hasn’t been implemented so far in Swift.
>>>
>>> If we agree we are not going to support class stored properties, there
>>> is and will be only one kind of stored properties for types and we
>>> only need one keyword to declare such properties.
>>>
>>> #### Class methods VS. static methods
>>>
>>> *Since calculated properties are also methods in essence they are also
>>> covered by this section.*
>>>
>>> The only difference is how methods are dispatched.
>>>
>>> Let’s see [how we handle it for instance
>>> methods](https://developer.apple.com/swift/blog/?id=27):
>>>
>>> * Methods are overridable hence dynamically dispatched by default.
>>> * In performance critical code use these techniques to restrict this
>>> dynamic behavior when it isn’t needed to improve performance:
>>>
>>> 1. Use the `final` keyword when we know that a declaration does
>>> not need to be overridden.
>>> 2. Infer `final` on declarations referenced in one file by
>>> applying the `private` keyword.
>>> 3. Use `Whole Module Optimization` to infer `final` on `internal`
>>> declarations.
>>>
>>> So why abandon this whole system to use another totally different one
>>> for differentiating `static dispatch` and `dynamic dispatch` for type
>>> methods?
>>>
>>> If we reuse this system for type methods, not only can we have a
>>> consistent design for both instance and type methods, but also we can
>>> get rid of the last place where two keywords for type member
>>> declarations are needed.
>>>
>>> ## Proposed solution
>>>
>>> 1. Use the keyword `type` to declare type properties and methods.
>>> 2. Type properties and methods are overridable hence dynamically
>>> dispatched by default. Use the `final` keyword or inferred `final` to
>>> make them final and statically dispatched, just like instance
>>> properties and methods.
>>> 3. Type properties can be stored or calculated, just like instance
properties.
>>>
>>> As you can see, it is a very simple and elegant design:
>>>
>>> * Just a single keyword `type` to differentiate type member
>>> declarations from instance member declarations. `type` is a good
>>> keyword because:
>>>
>>> 1. It is consistent with the wording of the concepts of `type
>>> properties` and `type methods`.
>>> 2. It is never used as a keyword before in Swift, Objective-C or
>>> C. There will be no conflicts or overloading of it meanings.
>>> * Except for that, how things are declared, differentiated and
>>> optimized are exactly the same in both type and instance world. Very
>>> consistent.
>>>
>>> ## Comparison with current design
>>>
>>> * Dynamic Dispatch VS. Static Dispatch
>>>
>>> ```swift
>>> // Old
>>> class Foo {
>>> func dynamicInstanceMethod() {}
>>> final func staticInstanceMethod() {}
>>>
>>> class func dynamicTypeMethod() {}
>>> static func staticTypeMethod() {}
>>> }
>>> ```
>>>
>>> ```swift
>>> // New
>>> class Foo {
>>> func dynamicInstanceMethod() {}
>>> final func staticInstanceMethod() {}
>>>
>>> type func dynamicTypeMethod() {}
>>> final type func staticTypeMethod() {}
>>> }
>>> ```
>>>
>>> * Stored Properties VS. Calculated Properties
>>>
>>> ```swift
>>> // Old
>>> class Bar {
>>> static let i = 1
>>>
>>> class var j: Int {
>>> return 1
>>> }
>>> }
>>> ```
>>>
>>> ```swift
>>> // New
>>> class Bar {
>>> type let i = 1
>>>
>>> type var j: Int {
>>> return 1
>>> }
>>> }
>>> ```
>>>
>>> * Struct Implementation VS. Class Implementation of Protocol
>>>
>>> ```swift
>>> // Old
>>> protocol P {
>>> static func foo()
>>> }
>>>
>>> struct S: P {
>>> static func foo() {}
>>> }
>>>
>>> class C: P {
>>> class func foo() {}
>>> }
>>> ```
>>>
>>> ```swift
>>> // New
>>> protocol P {
>>> type func foo()
>>> }
>>>
>>> struct S: P {
>>> type func foo() {}
>>> }
>>>
>>> class C: P {
>>> type func foo() {}
>>> }
>>> ```
>>>
>>> ## Impact on existing code
>>>
>>> With the help of a good migration tool, there will be no impact on
>>> existing code at all. And the migration rules are very clear and
>>> simple:
>>>
>>> * Map `static` to `type` in protocols.
>>> * Map `static` to `type` in structs and enums.
>>> * Map `class` to `type` and `static` to `final type` in classes.
>>>
>>> One concern I can think of is: because type methods are dynamically
>>> dispatched by default in the new design, will we forget to do the
>>> `final` optimization so the general performance of Swift code become
>>> worse?
>>>
>>> I think it is probably true. But we also forget to do the `final`
>>> optimization for instance methods from time to time. Since there are
>>> way more instance methods than type methods in most code the
>>> performance impact will be very small. Maybe this change is a good
>>> opportunity to remind us to do the `final` optimization for instance
>>> methods thus even results in a better general performance.
>>>
>>> And don’t forget we have the tools to automatically infer `final` for
>>> us in many cases if we write the proper code and use the proper
>>> compiler features.
>>>
>>> After all, it is mainly on us to write good code to produce good final
>>> products. If the system is consistent we’ll have better chances to
>>> master it and use it properly.
>>>
>>> ## Alternatives considered
>>>
>>> Alternatively we could:
>>> * Keep using `static` and `class` keywords.
>>> * Keep the confusion when implementing `static` protocol requirements
>>> using `class` properties and methods in conforming classes.
>>> * Keep the inconsistency between type member declarations and instance
>>> member declarations.
>>> * Keep overloading meanings on the `static` keyword that is already
>>> historically overloaded in C and Objective-C with which Swift must mix
>>> and match.
>>> _______________________________________________
>>> 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


(Ling Wang) #14

Now I understand your concerns. But you misunderstood my proposal. I'll restate my points about “type properties”:

1. Stored class properties(let’s call them “class instance variables” for better discussion about “stored type properties” below) are not very useful or needed. So we are not likely to add them to Swift. This one we both agree. So there is only one kind of stored properties for types and they are stored like global variables, which are now called “static stored properties“.

2. `type` properties in my proposal covers both stored properties and calculated properties. Except for the `type` keyword, the way they are declared are exactly the same as that of instance properties:

class Foo {
    type let i = 1 // stored type property
    type var k: Int { // calculated type property
        return 1
    }
} 

3. Since we’ve already excluded “class instance variables” in point 1, stored type properies in my proposal are certainly not “class instance variables”. They behave the same as the current “static stored properties”. This is where you misunderstood me.

So you don’t need the `final` keyword to make them “static”. If they are “stored”(VS calculated) they are “static”. We just don’t use `static` as the keyword.

Static storage is the implementation details. Just like global variable declarations don’t need `static` keyword though they use static storage, stored type property declarations don’t need `static` keyword to denote they use static storage. After all there is only one kind of stored type properties.

As you said most people expect type properties to be “static”, together with the fact that most people don’t know about “class instance variables”, stored type properties being “static” is simply the commonly accepted default behavior.

As to those who know about “class instance variables” we need to explain to them that stored type properties are not “class instance variables”. But since we need to tell them that Swift doens’t support “class instance variables” at all in the first place, it is not an extra complication.

Besides, we shouldn’t use `final` to denote storage at all for `final` is about inheritability/overridability not about storage.

Thanks for discussing with me:)

- Ling

···

On Dec 7, 2015, at 7:15 PM, Chris Lattner <clattner@apple.com> wrote:

On Dec 7, 2015, at 5:09 PM, Ling Wang <an00na@gmail.com <mailto:an00na@gmail.com>> wrote:

Class stored properties VS. static stored properties

You list many complaints about class properties, then go on to suggest that we replace “class” with “type”. It seems that your complaints aren’t actually relevant to the proposal, since you’re not actually removing them from the model. In fact, instead of “static var x” you’d have to write “final type var x”, which would be an unfortunate regression.

When you said "You list many complaints about class properties” you meant “class stored properties”, right?

If so I don’t think I’ve ever complained about it because Swift doesn’t support class stored properties yet. My points about class stored properties are:
1. Are they useful enough? Do we want it in Swift?
2. Are we going to add it in Swift? If yes, when?

Perhaps, but they are very low priority.

3. If no, then we only have one kind of type stored properties, why do we need two keywords for them?

You’re missing what I’m trying to say. With your design:

class Foo {
  type var x : Int
}

This would be a stored class property, which isn’t supported and won’t be for the forseeable. This would require people to write:

class Foo {
  final type var x : Int
}

This is a lot worse than:

class Foo {
  static var x : Int
}

... both in terms of boilerplate noise, but also in that it leads them down the wrong path. Many people would write “type var x : Int” wanting a static member, because they don’t understand how class variables work.

Your approach would make class members *more* prominent, not less. We’ve tried this, this is not a theoretical concern.

-Chris


(Matthew Johnson) #15

... both in terms of boilerplate noise, but also in that it leads them down the wrong path. Many people would write “type var x : Int” wanting a static member, because they don’t understand how class variables work.

Your approach would make class members *more* prominent, not less. We’ve tried this, this is not a theoretical concern.

This is only true as long as final is not the default. That is obviously an orthogonal issue but it is one I feel is worth reconsidering. It's interesting to note how final not being the default has caused difficulty in this corner of the language.

Maybe if final were the default and we decide to forgo class variables unification would become possible without the issues that arose the first time around.


(Chéyo Jiménez) #16

Hi Ling,

In April 2015 you said on your blog that "I was not convinced so I filed an
radar." It would seem to me that you are not convinced now either, even
after Chris explained that what you are asking for was
implemented, reverted and ultimately rejected. I appreciate the fact that
you are thinking and worry about the apparent inconstancy. I rather the
swift swift team spend more time focusing on ABI stability than on non
issue items. Swift is young. Who knows maybe your ideas will make it in a
future version of Swift.

wangling.me/2015/04/unify-type-properties-and-methods.html
https://devforums.apple.com/message/1123857

···

On Monday, December 7, 2015, an0 <an00na@gmail.com> wrote:

I read that. But that's a long time ago, Swift has evolved a lot since
then. I believe the Swift team may have some new ideas about it or at least
could take a look at the ideas in this proposal.

Do you have any ideas of your own about this proposal? I'd really like to
learn:)

On Mon, Dec 7, 2015 at 12:49 PM J. Cheyo Jimenez <cheyo@masters3d.com > <javascript:_e(%7B%7D,'cvml','cheyo@masters3d.com');>> wrote:

ChrisLattner wrote:

We considered unifying the syntax (e.g. using "type" as the keyword), but
that doesn't actually simply things. The keywords "class" and "static" are
good for familiarity and are quite descriptive (once you understand how +
methods work), and open the door for potentially adding truly static
methods to classes. The primary weirdness of this model is that protocols
have to pick a keyword (and we chose "class"), but on balance it is the
right tradeoff.

-Chris

Jul 5, 2014

https://devforums.apple.com/message/998365#998365

On Monday, December 7, 2015, an0 via swift-evolution < >> swift-evolution@swift.org >> <javascript:_e(%7B%7D,'cvml','swift-evolution@swift.org');>> wrote:

The idea is simple but the reasoning is long. So please bear with me.
You can read on github for a better reading experience:

https://github.com/an0/swift-evolution/blob/master/proposals/NNNN-unify-static-and-class-keywords.md
.

## Introduction

The coexistence of `static` and `class` keywords for declaring type
properties and methods is confusing and causes inconsistency between
type and instance member declarations. This document reasons why we
don’t need both and suggests we unify them with a better keyword
`type`.

## Motivation

### Confusion

One “language enhancement” of [Swift
1.2](
https://developer.apple.com/library/ios/releasenotes/DeveloperTools/RN-Xcode/Chapters/xc6_release_notes.html#//apple_ref/doc/uid/TP40001051-CH4-SW6
)
is:
> “static” methods and properties are now allowed in classes (as an
alias for class final). You are now allowed to declare static stored
properties in classes, which have global storage and are lazily initialized
on first access (like global variables). Protocols now declare type
requirements as static requirements instead of declaring them as class
requirements. (17198298)

If even the Swift team itself has difficulties in picking one from the
two and had to revert its initial decision after several revisions, we
know these keywords are indeed confusing.

So now protocols use `static` to declare type methods, when a class
adapts such protocols, should it implement those static methods, as
static methods or class methods?

But static means final, right? Does it mean we can not override these
methods in subclasses of the conforming class?

These kinds of unnecessary confusion and hesitation should be
resolved, and could if this proposal is implemented.

### Unnecessary and inconsistent differentiation

The `class` keyword is only used in classes. In the current
implementation of Swift the differences between `class` and `static`
are:

1. Class properties can only be calculated properties but not stored
properties.
2. Class methods(also calculated properties) are dynamically
dispatched while static ones are statically dispatched.

If we can eliminate the differences or find better ways to
differentiate we can use one unified keyword instead for declaring
type properties and methods.

Let’s see.

#### Class stored properties VS. static stored properties

If you use the `class` keyword to declare a stored property in a class
you will get this compiling error:
> class stored properties not yet supported in classes; did you mean
'static'?

So what are class stored properties? How are they different from
static stored properties?

As far as I know, class stored properties, if ever implemented in
Swift, “would be what Ruby calls ‘class instance
variables’”.<sup>[1](
https://twitter.com/UINT_MIN/status/584104757117095936)</sup>

So what are class instance variables?

The best explanation I can find is this
[one](http://martinfowler.com/bliki/ClassInstanceVariable.html) from
Martin Fowler.

Do we really want this feature in Swift? “If we didn't already have
these, would we add them to Swift 3?"

I strongly believe we won’t add it to Swift 3. Actually I believe we
will never add it to Swift, because its use cases are so rare which is
also why it hasn’t been implemented so far in Swift.

If we agree we are not going to support class stored properties, there
is and will be only one kind of stored properties for types and we
only need one keyword to declare such properties.

#### Class methods VS. static methods

*Since calculated properties are also methods in essence they are also
covered by this section.*

The only difference is how methods are dispatched.

Let’s see [how we handle it for instance
methods](https://developer.apple.com/swift/blog/?id=27):

* Methods are overridable hence dynamically dispatched by default.
* In performance critical code use these techniques to restrict this
dynamic behavior when it isn’t needed to improve performance:

    1. Use the `final` keyword when we know that a declaration does
not need to be overridden.
    2. Infer `final` on declarations referenced in one file by
applying the `private` keyword.
    3. Use `Whole Module Optimization` to infer `final` on `internal`
declarations.

So why abandon this whole system to use another totally different one
for differentiating `static dispatch` and `dynamic dispatch` for type
methods?

If we reuse this system for type methods, not only can we have a
consistent design for both instance and type methods, but also we can
get rid of the last place where two keywords for type member
declarations are needed.

## Proposed solution

1. Use the keyword `type` to declare type properties and methods.
2. Type properties and methods are overridable hence dynamically
dispatched by default. Use the `final` keyword or inferred `final` to
make them final and statically dispatched, just like instance
properties and methods.
3. Type properties can be stored or calculated, just like instance
properties.

As you can see, it is a very simple and elegant design:

* Just a single keyword `type` to differentiate type member
declarations from instance member declarations. `type` is a good
keyword because:

    1. It is consistent with the wording of the concepts of `type
properties` and `type methods`.
    2. It is never used as a keyword before in Swift, Objective-C or
C. There will be no conflicts or overloading of it meanings.
* Except for that, how things are declared, differentiated and
optimized are exactly the same in both type and instance world. Very
consistent.

## Comparison with current design

* Dynamic Dispatch VS. Static Dispatch

// Old
class Foo {
    func dynamicInstanceMethod() {}
    final func staticInstanceMethod() {}

    class func dynamicTypeMethod() {}
    static func staticTypeMethod() {}
}
// New
class Foo {
    func dynamicInstanceMethod() {}
    final func staticInstanceMethod() {}

    type func dynamicTypeMethod() {}
    final type func staticTypeMethod() {}
}

* Stored Properties VS. Calculated Properties

// Old
class Bar {
    static let i = 1

    class var j: Int {
        return 1
    }
}
// New
class Bar {
    type let i = 1

    type var j: Int {
        return 1
    }
}

* Struct Implementation VS. Class Implementation of Protocol

// Old
protocol P {
    static func foo()
}

struct S: P {
    static func foo() {}
}

class C: P {
    class func foo() {}
}
// New
protocol P {
    type func foo()
}

struct S: P {
    type func foo() {}
}

class C: P {
    type func foo() {}
}

## Impact on existing code

With the help of a good migration tool, there will be no impact on
existing code at all. And the migration rules are very clear and
simple:

* Map `static` to `type` in protocols.
* Map `static` to `type` in structs and enums.
* Map `class` to `type` and `static` to `final type` in classes.

One concern I can think of is: because type methods are dynamically
dispatched by default in the new design, will we forget to do the
`final` optimization so the general performance of Swift code become
worse?

I think it is probably true. But we also forget to do the `final`
optimization for instance methods from time to time. Since there are
way more instance methods than type methods in most code the
performance impact will be very small. Maybe this change is a good
opportunity to remind us to do the `final` optimization for instance
methods thus even results in a better general performance.

And don’t forget we have the tools to automatically infer `final` for
us in many cases if we write the proper code and use the proper
compiler features.

After all, it is mainly on us to write good code to produce good final
products. If the system is consistent we’ll have better chances to
master it and use it properly.

## Alternatives considered

Alternatively we could:
* Keep using `static` and `class` keywords.
* Keep the confusion when implementing `static` protocol requirements
using `class` properties and methods in conforming classes.
* Keep the inconsistency between type member declarations and instance
member declarations.
* Keep overloading meanings on the `static` keyword that is already
historically overloaded in C and Objective-C with which Swift must mix
and match.

_______________________________________________

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


(John McCall) #17

One important difference between “static” and “class” on a class is the behavior of storage. In principle, a static variable in a class is just a rescoped global (although it is unclear how this is affected by generics). A class variable in a class is conceptually a member of the class, and subclasses should get a separate copy.

I understand that this is the case in general, but is it still the case when a class variable is marked as final in its initial declaration?

Yes. “final” means that it can’t be given different semantics in a subclass, not that it’s no longer a separate variable.

John.

···

On Dec 7, 2015, at 11:34 AM, Matthew Johnson <matthew@anandabits.com> wrote:

If class variables do behave differently even when declared final I wonder whether the use cases for this behavior are compelling enough to justify the conceptual complexity of two different keywords. I would be very interested in seeing examples of using a final class variable where separate storage for each subclass is desirable and useful.


(Matthew Johnson) #18

I must have missed the initial link to the proposal. This is very well thought out and I support it very strongly. My opinion on the keyword is not strong enough to matter and I would support whatever keyword has the most consensus.

I think my own confusion about static vs final class demonstrates the problem with the current state.

···

Sent from my iPad

On Dec 7, 2015, at 1:38 PM, an0 <an00na@gmail.com> wrote:

I've already addressed that under "Class stored properties VS. static
stored properties"(https://github.com/an0/swift-evolution/blob/master/proposals/NNNN-unify-static-and-class-keywords.md#class-stored-properties-vs-static-stored-properties).
I don't think we'll add class stored properties to Swift though. It is
one of the premises of this proposal.

On Mon, Dec 7, 2015 at 1:22 PM, John McCall <rjmccall@apple.com> wrote:

On Dec 7, 2015, at 10:56 AM, Matthew Johnson via swift-evolution <swift-evolution@swift.org> wrote:

I think unifying these keywords would make a lot of sense, but neither would really be suitable as the unified choice. 'class' would be out of place in structs and enums. 'static' would be out of place for members that can be overridden in a class.

If we do unify this keyword, I believe combining it with 'final' in a class would recover the behavior we currently get when using 'static' in a class. (If this is not correct I would want to know how we achieve that behavior with the unified keyword)

There are a lot of drawbacks to using 'type' and I think we should find something better.

One important difference between “static” and “class” on a class is the behavior of storage. In principle, a static variable in a class is just a rescoped global (although it is unclear how this is affected by generics). A class variable in a class is conceptually a member of the class, and subclasses should get a separate copy.

John.

Sent from my iPad

On Dec 7, 2015, at 12:11 PM, Ling Wang via swift-evolution <swift-evolution@swift.org> wrote:

`type` is the best I can come up with so far. Using `type` to declare type members inside types is completely parallel with using `class` to declare class members inside classes, so conceptually it should be easy to accept. It may look a bit uncomfortable at first simply because it is new and different, especially to those with C++ and Java experiences.

On Dec 7, 2015, at 11:01 AM, David Hart <david@hartbit.com> wrote:

I really like this proposition, but I'm not a fan of the keyword, but can't think of anything better right now...

On 07 Dec 2015, at 17:13, an0 via swift-evolution <swift-evolution@swift.org> wrote:

The idea is simple but the reasoning is long. So please bear with me.
You can read on github for a better reading experience:
https://github.com/an0/swift-evolution/blob/master/proposals/NNNN-unify-static-and-class-keywords.md.

## Introduction

The coexistence of `static` and `class` keywords for declaring type
properties and methods is confusing and causes inconsistency between
type and instance member declarations. This document reasons why we
don’t need both and suggests we unify them with a better keyword
`type`.

## Motivation

### Confusion

One “language enhancement” of [Swift
1.2](https://developer.apple.com/library/ios/releasenotes/DeveloperTools/RN-Xcode/Chapters/xc6_release_notes.html#//apple_ref/doc/uid/TP40001051-CH4-SW6)
is:

“static” methods and properties are now allowed in classes (as an alias for class final). You are now allowed to declare static stored properties in classes, which have global storage and are lazily initialized on first access (like global variables). Protocols now declare type requirements as static requirements instead of declaring them as class requirements. (17198298)

If even the Swift team itself has difficulties in picking one from the
two and had to revert its initial decision after several revisions, we
know these keywords are indeed confusing.

So now protocols use `static` to declare type methods, when a class
adapts such protocols, should it implement those static methods, as
static methods or class methods?

But static means final, right? Does it mean we can not override these
methods in subclasses of the conforming class?

These kinds of unnecessary confusion and hesitation should be
resolved, and could if this proposal is implemented.

### Unnecessary and inconsistent differentiation

The `class` keyword is only used in classes. In the current
implementation of Swift the differences between `class` and `static`
are:

1. Class properties can only be calculated properties but not stored properties.
2. Class methods(also calculated properties) are dynamically
dispatched while static ones are statically dispatched.

If we can eliminate the differences or find better ways to
differentiate we can use one unified keyword instead for declaring
type properties and methods.

Let’s see.

#### Class stored properties VS. static stored properties

If you use the `class` keyword to declare a stored property in a class
you will get this compiling error:

class stored properties not yet supported in classes; did you mean 'static'?

So what are class stored properties? How are they different from
static stored properties?

As far as I know, class stored properties, if ever implemented in
Swift, “would be what Ruby calls ‘class instance
variables’”.<sup>[1](https://twitter.com/UINT_MIN/status/584104757117095936)</sup>

So what are class instance variables?

The best explanation I can find is this
[one](http://martinfowler.com/bliki/ClassInstanceVariable.html) from
Martin Fowler.

Do we really want this feature in Swift? “If we didn't already have
these, would we add them to Swift 3?"

I strongly believe we won’t add it to Swift 3. Actually I believe we
will never add it to Swift, because its use cases are so rare which is
also why it hasn’t been implemented so far in Swift.

If we agree we are not going to support class stored properties, there
is and will be only one kind of stored properties for types and we
only need one keyword to declare such properties.

#### Class methods VS. static methods

*Since calculated properties are also methods in essence they are also
covered by this section.*

The only difference is how methods are dispatched.

Let’s see [how we handle it for instance
methods](https://developer.apple.com/swift/blog/?id=27):

* Methods are overridable hence dynamically dispatched by default.
* In performance critical code use these techniques to restrict this
dynamic behavior when it isn’t needed to improve performance:

1. Use the `final` keyword when we know that a declaration does
not need to be overridden.
2. Infer `final` on declarations referenced in one file by
applying the `private` keyword.
3. Use `Whole Module Optimization` to infer `final` on `internal`
declarations.

So why abandon this whole system to use another totally different one
for differentiating `static dispatch` and `dynamic dispatch` for type
methods?

If we reuse this system for type methods, not only can we have a
consistent design for both instance and type methods, but also we can
get rid of the last place where two keywords for type member
declarations are needed.

## Proposed solution

1. Use the keyword `type` to declare type properties and methods.
2. Type properties and methods are overridable hence dynamically
dispatched by default. Use the `final` keyword or inferred `final` to
make them final and statically dispatched, just like instance
properties and methods.
3. Type properties can be stored or calculated, just like instance properties.

As you can see, it is a very simple and elegant design:

* Just a single keyword `type` to differentiate type member
declarations from instance member declarations. `type` is a good
keyword because:

1. It is consistent with the wording of the concepts of `type
properties` and `type methods`.
2. It is never used as a keyword before in Swift, Objective-C or
C. There will be no conflicts or overloading of it meanings.
* Except for that, how things are declared, differentiated and
optimized are exactly the same in both type and instance world. Very
consistent.

## Comparison with current design

* Dynamic Dispatch VS. Static Dispatch

// Old
class Foo {
func dynamicInstanceMethod() {}
final func staticInstanceMethod() {}

class func dynamicTypeMethod() {}
static func staticTypeMethod() {}
}
// New
class Foo {
func dynamicInstanceMethod() {}
final func staticInstanceMethod() {}

type func dynamicTypeMethod() {}
final type func staticTypeMethod() {}
}

* Stored Properties VS. Calculated Properties

// Old
class Bar {
static let i = 1

class var j: Int {
   return 1
}
}
// New
class Bar {
type let i = 1

type var j: Int {
   return 1
}
}

* Struct Implementation VS. Class Implementation of Protocol

// Old
protocol P {
static func foo()
}

struct S: P {
static func foo() {}
}

class C: P {
class func foo() {}
}
// New
protocol P {
type func foo()
}

struct S: P {
type func foo() {}
}

class C: P {
type func foo() {}
}

## Impact on existing code

With the help of a good migration tool, there will be no impact on
existing code at all. And the migration rules are very clear and
simple:

* Map `static` to `type` in protocols.
* Map `static` to `type` in structs and enums.
* Map `class` to `type` and `static` to `final type` in classes.

One concern I can think of is: because type methods are dynamically
dispatched by default in the new design, will we forget to do the
`final` optimization so the general performance of Swift code become
worse?

I think it is probably true. But we also forget to do the `final`
optimization for instance methods from time to time. Since there are
way more instance methods than type methods in most code the
performance impact will be very small. Maybe this change is a good
opportunity to remind us to do the `final` optimization for instance
methods thus even results in a better general performance.

And don’t forget we have the tools to automatically infer `final` for
us in many cases if we write the proper code and use the proper
compiler features.

After all, it is mainly on us to write good code to produce good final
products. If the system is consistent we’ll have better chances to
master it and use it properly.

## Alternatives considered

Alternatively we could:
* Keep using `static` and `class` keywords.
* Keep the confusion when implementing `static` protocol requirements
using `class` properties and methods in conforming classes.
* Keep the inconsistency between type member declarations and instance
member declarations.
* Keep overloading meanings on the `static` keyword that is already
historically overloaded in C and Objective-C with which Swift must mix
and match.
_______________________________________________
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

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

--
wangling.me


(Ling Wang) #19

The fact that there are other issues does not mean this is non issue. You
agree we have inconsistency here, right?

Also, there are misunderstandings by Chris to my proposal. Please read my
last response to him. If these misunderstandings are resolved I believe
we'll have much more common ground to build a better design that is never
tried before.

···

On Mon, Dec 7, 2015 at 10:22 PM J. Cheyo Jimenez <cheyo@masters3d.com> wrote:

Hi Ling,

In April 2015 you said on your blog that "I was not convinced so I filed
an radar." It would seem to me that you are not convinced now
either, even after Chris explained that what you are asking for was
implemented, reverted and ultimately rejected. I appreciate the fact that
you are thinking and worry about the apparent inconstancy. I rather the
swift swift team spend more time focusing on ABI stability than on non
issue items. Swift is young. Who knows maybe your ideas will make it in a
future version of Swift.

wangling.me/2015/04/unify-type-properties-and-methods.html
https://devforums.apple.com/message/1123857

On Monday, December 7, 2015, an0 <an00na@gmail.com> wrote:

I read that. But that's a long time ago, Swift has evolved a lot since
then. I believe the Swift team may have some new ideas about it or at least
could take a look at the ideas in this proposal.

Do you have any ideas of your own about this proposal? I'd really like to
learn:)

On Mon, Dec 7, 2015 at 12:49 PM J. Cheyo Jimenez <cheyo@masters3d.com> >> wrote:

ChrisLattner wrote:

We considered unifying the syntax (e.g. using "type" as the keyword),
but that doesn't actually simply things. The keywords "class" and "static"
are good for familiarity and are quite descriptive (once you understand how
+ methods work), and open the door for potentially adding truly static
methods to classes. The primary weirdness of this model is that protocols
have to pick a keyword (and we chose "class"), but on balance it is the
right tradeoff.

-Chris

Jul 5, 2014

https://devforums.apple.com/message/998365#998365

On Monday, December 7, 2015, an0 via swift-evolution < >>> swift-evolution@swift.org> wrote:

The idea is simple but the reasoning is long. So please bear with me.
You can read on github for a better reading experience:

https://github.com/an0/swift-evolution/blob/master/proposals/NNNN-unify-static-and-class-keywords.md
.

## Introduction

The coexistence of `static` and `class` keywords for declaring type
properties and methods is confusing and causes inconsistency between
type and instance member declarations. This document reasons why we
don’t need both and suggests we unify them with a better keyword
`type`.

## Motivation

### Confusion

One “language enhancement” of [Swift
1.2](
https://developer.apple.com/library/ios/releasenotes/DeveloperTools/RN-Xcode/Chapters/xc6_release_notes.html#//apple_ref/doc/uid/TP40001051-CH4-SW6
)
is:
> “static” methods and properties are now allowed in classes (as an
alias for class final). You are now allowed to declare static stored
properties in classes, which have global storage and are lazily initialized
on first access (like global variables). Protocols now declare type
requirements as static requirements instead of declaring them as class
requirements. (17198298)

If even the Swift team itself has difficulties in picking one from the
two and had to revert its initial decision after several revisions, we
know these keywords are indeed confusing.

So now protocols use `static` to declare type methods, when a class
adapts such protocols, should it implement those static methods, as
static methods or class methods?

But static means final, right? Does it mean we can not override these
methods in subclasses of the conforming class?

These kinds of unnecessary confusion and hesitation should be
resolved, and could if this proposal is implemented.

### Unnecessary and inconsistent differentiation

The `class` keyword is only used in classes. In the current
implementation of Swift the differences between `class` and `static`
are:

1. Class properties can only be calculated properties but not stored
properties.
2. Class methods(also calculated properties) are dynamically
dispatched while static ones are statically dispatched.

If we can eliminate the differences or find better ways to
differentiate we can use one unified keyword instead for declaring
type properties and methods.

Let’s see.

#### Class stored properties VS. static stored properties

If you use the `class` keyword to declare a stored property in a class
you will get this compiling error:
> class stored properties not yet supported in classes; did you mean
'static'?

So what are class stored properties? How are they different from
static stored properties?

As far as I know, class stored properties, if ever implemented in
Swift, “would be what Ruby calls ‘class instance
variables’”.<sup>[1](
https://twitter.com/UINT_MIN/status/584104757117095936)</sup>

So what are class instance variables?

The best explanation I can find is this
[one](http://martinfowler.com/bliki/ClassInstanceVariable.html) from
Martin Fowler.

Do we really want this feature in Swift? “If we didn't already have
these, would we add them to Swift 3?"

I strongly believe we won’t add it to Swift 3. Actually I believe we
will never add it to Swift, because its use cases are so rare which is
also why it hasn’t been implemented so far in Swift.

If we agree we are not going to support class stored properties, there
is and will be only one kind of stored properties for types and we
only need one keyword to declare such properties.

#### Class methods VS. static methods

*Since calculated properties are also methods in essence they are also
covered by this section.*

The only difference is how methods are dispatched.

Let’s see [how we handle it for instance
methods](https://developer.apple.com/swift/blog/?id=27):

* Methods are overridable hence dynamically dispatched by default.
* In performance critical code use these techniques to restrict this
dynamic behavior when it isn’t needed to improve performance:

    1. Use the `final` keyword when we know that a declaration does
not need to be overridden.
    2. Infer `final` on declarations referenced in one file by
applying the `private` keyword.
    3. Use `Whole Module Optimization` to infer `final` on `internal`
declarations.

So why abandon this whole system to use another totally different one
for differentiating `static dispatch` and `dynamic dispatch` for type
methods?

If we reuse this system for type methods, not only can we have a
consistent design for both instance and type methods, but also we can
get rid of the last place where two keywords for type member
declarations are needed.

## Proposed solution

1. Use the keyword `type` to declare type properties and methods.
2. Type properties and methods are overridable hence dynamically
dispatched by default. Use the `final` keyword or inferred `final` to
make them final and statically dispatched, just like instance
properties and methods.
3. Type properties can be stored or calculated, just like instance
properties.

As you can see, it is a very simple and elegant design:

* Just a single keyword `type` to differentiate type member
declarations from instance member declarations. `type` is a good
keyword because:

    1. It is consistent with the wording of the concepts of `type
properties` and `type methods`.
    2. It is never used as a keyword before in Swift, Objective-C or
C. There will be no conflicts or overloading of it meanings.
* Except for that, how things are declared, differentiated and
optimized are exactly the same in both type and instance world. Very
consistent.

## Comparison with current design

* Dynamic Dispatch VS. Static Dispatch

// Old
class Foo {
    func dynamicInstanceMethod() {}
    final func staticInstanceMethod() {}

    class func dynamicTypeMethod() {}
    static func staticTypeMethod() {}
}
// New
class Foo {
    func dynamicInstanceMethod() {}
    final func staticInstanceMethod() {}

    type func dynamicTypeMethod() {}
    final type func staticTypeMethod() {}
}

* Stored Properties VS. Calculated Properties

// Old
class Bar {
    static let i = 1

    class var j: Int {
        return 1
    }
}
// New
class Bar {
    type let i = 1

    type var j: Int {
        return 1
    }
}

* Struct Implementation VS. Class Implementation of Protocol

// Old
protocol P {
    static func foo()
}

struct S: P {
    static func foo() {}
}

class C: P {
    class func foo() {}
}
// New
protocol P {
    type func foo()
}

struct S: P {
    type func foo() {}
}

class C: P {
    type func foo() {}
}

## Impact on existing code

With the help of a good migration tool, there will be no impact on
existing code at all. And the migration rules are very clear and
simple:

* Map `static` to `type` in protocols.
* Map `static` to `type` in structs and enums.
* Map `class` to `type` and `static` to `final type` in classes.

One concern I can think of is: because type methods are dynamically
dispatched by default in the new design, will we forget to do the
`final` optimization so the general performance of Swift code become
worse?

I think it is probably true. But we also forget to do the `final`
optimization for instance methods from time to time. Since there are
way more instance methods than type methods in most code the
performance impact will be very small. Maybe this change is a good
opportunity to remind us to do the `final` optimization for instance
methods thus even results in a better general performance.

And don’t forget we have the tools to automatically infer `final` for
us in many cases if we write the proper code and use the proper
compiler features.

After all, it is mainly on us to write good code to produce good final
products. If the system is consistent we’ll have better chances to
master it and use it properly.

## Alternatives considered

Alternatively we could:
* Keep using `static` and `class` keywords.
* Keep the confusion when implementing `static` protocol requirements
using `class` properties and methods in conforming classes.
* Keep the inconsistency between type member declarations and instance
member declarations.
* Keep overloading meanings on the `static` keyword that is already
historically overloaded in C and Objective-C with which Swift must mix
and match.

_______________________________________________

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


(Daniel Valls Estella) #20

Just if it helps someway, in my opinion:

- static is well known keyword modifier from long ago, but I think is an unfortunate one because is named that way from a complier point fo view, not from a language programmer user.

- I don’t understand static as having an implicit final behaviour.

- It seems we want to mix in one word parallel variables modifiers when is not a goal reduce code typing.

- I found confusing using class keyword instead of static just to note that a static computed variable is not final (same for methods). More when the language provides the final keyword to identify this behaviour.

- why not ?

class SomeClass {

    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {
        return 27
    }
    static final var nonOverrideableComputedTypeProperty: Int {
        return 107
    }
}

-But as I mentioned I think static is not a good keyword, only we have been used to it.

Maybe shared ? Adding overridable in case?

class SomeClass {
    shared var storedTypeProperty = “Some value."
    shared var computedTypeProperty: Int {
        return 27
    }
    shared overridable var overrideableComputedTypeProperty: Int {
        return 107
    }
}

Or:

class SomeClass {
    shared var storedTypeProperty = “Some value."
    shared var computedTypeProperty: Int {
        return 27
    }
    shared final var nonOverrideableComputedTypeProperty: Int {
        return 107
    }
}

Thanks,

Daniel

Fragment de: Apple Inc. “The Swift Programming Language (Swift 2.2)“. iBooks.

Fragment de: Apple Inc. “The Swift Programming Language (Swift 2.2)“. iBooks.

···

El 8 des 2015, a les 5:22, J. Cheyo Jimenez via swift-evolution <swift-evolution@swift.org> va escriure:

Hi Ling,

In April 2015 you said on your blog that "I was not convinced so I filed an radar." It would seem to me that you are not convinced now either, even after Chris explained that what you are asking for was implemented, reverted and ultimately rejected. I appreciate the fact that you are thinking and worry about the apparent inconstancy. I rather the swift swift team spend more time focusing on ABI stability than on non issue items. Swift is young. Who knows maybe your ideas will make it in a future version of Swift.

wangling.me/2015/04/unify-type-properties-and-methods.html <http://wangling.me/2015/04/unify-type-properties-and-methods.html>
https://devforums.apple.com/message/1123857

On Monday, December 7, 2015, an0 <an00na@gmail.com <mailto:an00na@gmail.com>> wrote:
I read that. But that's a long time ago, Swift has evolved a lot since then. I believe the Swift team may have some new ideas about it or at least could take a look at the ideas in this proposal.

Do you have any ideas of your own about this proposal? I'd really like to learn:)

On Mon, Dec 7, 2015 at 12:49 PM J. Cheyo Jimenez <cheyo@masters3d.com <javascript:_e(%7B%7D,'cvml','cheyo@masters3d.com');>> wrote:
ChrisLattner wrote:

We considered unifying the syntax (e.g. using "type" as the keyword), but that doesn't actually simply things. The keywords "class" and "static" are good for familiarity and are quite descriptive (once you understand how + methods work), and open the door for potentially adding truly static methods to classes. The primary weirdness of this model is that protocols have to pick a keyword (and we chose "class"), but on balance it is the right tradeoff.

-Chris
Jul 5, 2014

https://devforums.apple.com/message/998365#998365

On Monday, December 7, 2015, an0 via swift-evolution <swift-evolution@swift.org <javascript:_e(%7B%7D,'cvml','swift-evolution@swift.org');>> wrote:
The idea is simple but the reasoning is long. So please bear with me.
You can read on github for a better reading experience:
https://github.com/an0/swift-evolution/blob/master/proposals/NNNN-unify-static-and-class-keywords.md.

## Introduction

The coexistence of `static` and `class` keywords for declaring type
properties and methods is confusing and causes inconsistency between
type and instance member declarations. This document reasons why we
don’t need both and suggests we unify them with a better keyword
`type`.

## Motivation

### Confusion

One “language enhancement” of [Swift
1.2](https://developer.apple.com/library/ios/releasenotes/DeveloperTools/RN-Xcode/Chapters/xc6_release_notes.html#//apple_ref/doc/uid/TP40001051-CH4-SW6)
is:
> “static” methods and properties are now allowed in classes (as an alias for class final). You are now allowed to declare static stored properties in classes, which have global storage and are lazily initialized on first access (like global variables). Protocols now declare type requirements as static requirements instead of declaring them as class requirements. (17198298)

If even the Swift team itself has difficulties in picking one from the
two and had to revert its initial decision after several revisions, we
know these keywords are indeed confusing.

So now protocols use `static` to declare type methods, when a class
adapts such protocols, should it implement those static methods, as
static methods or class methods?

But static means final, right? Does it mean we can not override these
methods in subclasses of the conforming class?

These kinds of unnecessary confusion and hesitation should be
resolved, and could if this proposal is implemented.

### Unnecessary and inconsistent differentiation

The `class` keyword is only used in classes. In the current
implementation of Swift the differences between `class` and `static`
are:

1. Class properties can only be calculated properties but not stored properties.
2. Class methods(also calculated properties) are dynamically
dispatched while static ones are statically dispatched.

If we can eliminate the differences or find better ways to
differentiate we can use one unified keyword instead for declaring
type properties and methods.

Let’s see.

#### Class stored properties VS. static stored properties

If you use the `class` keyword to declare a stored property in a class
you will get this compiling error:
> class stored properties not yet supported in classes; did you mean 'static'?

So what are class stored properties? How are they different from
static stored properties?

As far as I know, class stored properties, if ever implemented in
Swift, “would be what Ruby calls ‘class instance
variables’”.<sup>[1](https://twitter.com/UINT_MIN/status/584104757117095936)</sup>

So what are class instance variables?

The best explanation I can find is this
[one](http://martinfowler.com/bliki/ClassInstanceVariable.html) from
Martin Fowler.

Do we really want this feature in Swift? “If we didn't already have
these, would we add them to Swift 3?"

I strongly believe we won’t add it to Swift 3. Actually I believe we
will never add it to Swift, because its use cases are so rare which is
also why it hasn’t been implemented so far in Swift.

If we agree we are not going to support class stored properties, there
is and will be only one kind of stored properties for types and we
only need one keyword to declare such properties.

#### Class methods VS. static methods

*Since calculated properties are also methods in essence they are also
covered by this section.*

The only difference is how methods are dispatched.

Let’s see [how we handle it for instance
methods](https://developer.apple.com/swift/blog/?id=27 <https://developer.apple.com/swift/blog/?id=27>):

* Methods are overridable hence dynamically dispatched by default.
* In performance critical code use these techniques to restrict this
dynamic behavior when it isn’t needed to improve performance:

    1. Use the `final` keyword when we know that a declaration does
not need to be overridden.
    2. Infer `final` on declarations referenced in one file by
applying the `private` keyword.
    3. Use `Whole Module Optimization` to infer `final` on `internal`
declarations.

So why abandon this whole system to use another totally different one
for differentiating `static dispatch` and `dynamic dispatch` for type
methods?

If we reuse this system for type methods, not only can we have a
consistent design for both instance and type methods, but also we can
get rid of the last place where two keywords for type member
declarations are needed.

## Proposed solution

1. Use the keyword `type` to declare type properties and methods.
2. Type properties and methods are overridable hence dynamically
dispatched by default. Use the `final` keyword or inferred `final` to
make them final and statically dispatched, just like instance
properties and methods.
3. Type properties can be stored or calculated, just like instance properties.

As you can see, it is a very simple and elegant design:

* Just a single keyword `type` to differentiate type member
declarations from instance member declarations. `type` is a good
keyword because:

    1. It is consistent with the wording of the concepts of `type
properties` and `type methods`.
    2. It is never used as a keyword before in Swift, Objective-C or
C. There will be no conflicts or overloading of it meanings.
* Except for that, how things are declared, differentiated and
optimized are exactly the same in both type and instance world. Very
consistent.

## Comparison with current design

* Dynamic Dispatch VS. Static Dispatch

// Old
class Foo {
    func dynamicInstanceMethod() {}
    final func staticInstanceMethod() {}

    class func dynamicTypeMethod() {}
    static func staticTypeMethod() {}
}
// New
class Foo {
    func dynamicInstanceMethod() {}
    final func staticInstanceMethod() {}

    type func dynamicTypeMethod() {}
    final type func staticTypeMethod() {}
}

* Stored Properties VS. Calculated Properties

// Old
class Bar {
    static let i = 1

    class var j: Int {
        return 1
    }
}
// New
class Bar {
    type let i = 1

    type var j: Int {
        return 1
    }
}

* Struct Implementation VS. Class Implementation of Protocol

// Old
protocol P {
    static func foo()
}

struct S: P {
    static func foo() {}
}

class C: P {
    class func foo() {}
}
// New
protocol P {
    type func foo()
}

struct S: P {
    type func foo() {}
}

class C: P {
    type func foo() {}
}

## Impact on existing code

With the help of a good migration tool, there will be no impact on
existing code at all. And the migration rules are very clear and
simple:

* Map `static` to `type` in protocols.
* Map `static` to `type` in structs and enums.
* Map `class` to `type` and `static` to `final type` in classes.

One concern I can think of is: because type methods are dynamically
dispatched by default in the new design, will we forget to do the
`final` optimization so the general performance of Swift code become
worse?

I think it is probably true. But we also forget to do the `final`
optimization for instance methods from time to time. Since there are
way more instance methods than type methods in most code the
performance impact will be very small. Maybe this change is a good
opportunity to remind us to do the `final` optimization for instance
methods thus even results in a better general performance.

And don’t forget we have the tools to automatically infer `final` for
us in many cases if we write the proper code and use the proper
compiler features.

After all, it is mainly on us to write good code to produce good final
products. If the system is consistent we’ll have better chances to
master it and use it properly.

## Alternatives considered

Alternatively we could:
* Keep using `static` and `class` keywords.
* Keep the confusion when implementing `static` protocol requirements
using `class` properties and methods in conforming classes.
* Keep the inconsistency between type member declarations and instance
member declarations.
* Keep overloading meanings on the `static` keyword that is already
historically overloaded in C and Objective-C with which Swift must mix
and match.
_______________________________________________
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