[swift-evolution] Unify `static` and `class` keywords

Ling Wang an00na at gmail.com
Wed Dec 9 10:23:08 CST 2015

This is a legit concern that I didn’t consider before.

I think there are several options, from the most general to the most subtle:
1. Stored type properties are implicit `final`, so behave exactly the same as the current static stored properties.
2. Stored type vars are implicit `final`, as you suggested, so behave exactly the same as the current static stored vars. All other type properties(including stored type lets) are normally overridable.
3. Store type vars are overridable but can not be observed. 

There could be a even more subtle option if my understanding of how classes exist in runtime is correct.

In my understanding, classes exist as singleton instances of their meta classes. If it is true, which I believe is the image in most people’s heads if they know about meta classes, then the class objects tree is exactly the same as the class hierarchy tree. Every subclass object contains(or points to) its super class object in its layout. The super class part is shared by all subclass objects and the super class object per se. So stored type properties are conceptually and naturally shared by the super class and all its subclasses, which behave exactly like the current static stored properties.

In this modal, the 4th option is:
4. Stored type vars are overridable and observable. When they are assigned new values, all their property observers defined in the class hierarchy are called, calling order is not significant, the reason of which will be addressed later.

Unfortunately, there is one last catch: if more than one classes assign a value to the property within their didSet observer, the final result is undefined.

This issue can not even be resolved by ordering observer calls from top to bottom in the class hierarchy because we can not meaningfully define the order within the same level if there are more than one subclasses in it.

So one addition to option 4:
4-1. Stored type vars’ didSet observers are not allowed to reassign value to the observed property.

But it is such a corner case that probably this limitation is acceptable.

What do you think? Is my understanding of class objects correct? Which option do you like best?

- Ling

> On Dec 8, 2015, at 5:40 PM, Jordan Rose <jordan_rose at apple.com> wrote:
>> On Dec 7, 2015, at 19:12, Ling Wang via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> Besides, we shouldn’t use `final` to denote storage at all for `final` is about inheritability/overridability not about storage.
> Please remember that stored properties can be overridden in Swift:
> class Base {
>   /*instance*/ var flag: Bool = true
> }
> class Sub : Base {
>   override var flag: Bool {
>     didSet {
>       if flag { print("The flag was set!") }
>     }
>   }
> }
> This is theoretically possible at the class level as well, but doesn't really make sense for what's currently spelled "static var", since you'd be accessing the same storage in different ways. Does the proposal mean that a stored "type var" is non-overrideable, but a computed "type var" is overrideable, implicitly?
> Jordan

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151209/4f47a91a/attachment.html>

More information about the swift-evolution mailing list