[swift-evolution] Notes from Swift core team 2016-04-20 design discussion

Alex Martini amartini at apple.com
Thu Apr 21 10:58:03 CDT 2016

To help keep proposals moving forward, the Swift core team has set aside some time specifically for design discussions of upcoming proposals.  Below are some rough notes from the yesterday's discussion.

These are informal comments, intended to guide the proposals in directions that draw constructive feedback. You are welcome to ignore the feedback, agree with it, or disagree with it.  As always, the formal decision doesn't happen until after the review period ends.

SE-0068: Expanding Swift Self to class members and value types <file:///Users/alexmartini/DevPubs%20Git%20Repositories/Swift%20Language%20Review/_build/html/LR_MeetingNotes/2016-04-20.html#se-0068-expanding-swift-self-to-class-members-and-value-types>
https://github.com/apple/swift-evolution/blob/master/proposals/0068-universal-self.md <https://github.com/apple/swift-evolution/blob/master/proposals/0068-universal-self.md>
We have one keyword left in the language, dynamicType, which is camel cased. This proposal renames it to Self instead.

In a static function today, self.dynamicType will give you a metatype but the non-member Self will not. The most useful reason to reference it is to call an initializer. It makes accessing the metatype weirder. It’s not Self.Type; that’s a type — you have to spell it Self.type.

Quiz time! What do each of the permutations mean?

The number of capital letters gives you the level of meta-ness. This is very subtle, which is probably not a good thing.

Another approach would be to introduce a new dynamictype keyword that doesn’t need to be accessed as a member of self, and keep Self the way it is.  Self should work in structs as a type alias.

Why don’t we turn this into a standard library function? It’s not something you need so often that the member access is very valuable. Putting it in the standard library as dynamicType(_:) does still allow for that function to be implemented using compiler magic.

func dynamicType<T>(_: T) -> T.Type { }
We have a proposal to remove .self on types. One reason .self exists is to avoid the mistake of writing let x = Int — the compiler will give you a weird type error later on in code if the value of x is what we today call Int.self but you meant to call the Int() initializer. Creating a metatype is not a common operation, so doing it explicitly is a good thing.

It’s weird that you can use the metatype directly to construct something or to do member access, but you can’t access it as a bare value.

Coming back to this proposal, if we removed .self why would we want to add .Self?

If you have a variable whose value is a metatype, you also keep its name in lower case. So Self makes a little less sense from that aspect too.

Another perspective is that .dynamicType is just an implicitly synthesized property on all type.

We do have other keywords that follow the dot on types, Int.Type and Fooable.Protocol, so this isn’t the only thing. Those things are magic nested types.

Subjectively, having dynamicType as a member feels weird.

If .self goes away, the four-self example above is simplified, and .Self doesn’t make sense anymore. There’s also the difference that .Self would be a runtime thing.

What to do about optional requirements <file:///Users/alexmartini/DevPubs%20Git%20Repositories/Swift%20Language%20Review/_build/html/LR_MeetingNotes/2016-04-20.html#what-to-do-about-optional-requirements>
http://thread.gmane.org/gmane.comp.lang.swift.evolution/14046 <http://thread.gmane.org/gmane.comp.lang.swift.evolution/14046>
People commonly ask why optional only works on Objective-C protocols, and the responses they get are usually that in Swift code you should reshape your protocols. As a starting assumption, we’re not making optionl work in Swift. So what do we do about this as part of the interoperability code?

People do write these, but it’s often because they’re writing a delegate protocol and they’re following the example of Cocoa frameworks.

Roughly three things we can do:

Rename it to make it clearly an Objective-C interop feature. We could also forbid you actually spelling it in Swift code. That doesn’t work well because it breaks your ability to write code in Swift that has Objective-C clients — those clients won’t get the default implementation from the extensions like you would use with Swift clients instead of creating optional requirements.
Modeling optional requirements as a function of optional type such as ((A, B) -> C)? doesn’t work well. For example, properties can have optional type and they can be optional requirements, so you would end up having to deal with a lot of extra complexity due to double-optionals and likely want better code completion so you could type it all out.
You force the default implementation to be visible from all callers, and you do the dispatch at the call site. The only advantage of this is that it takes optional requirements out of the language entirely. If you wanted to implement the (somewhat common) pattern of checking whether a type implements an optional requirement, you would have to use a respondsToSelector check.
The best pattern we’ve seen for checking conformance and using different code paths based on that is to use finer-grained protocols. (But there are still issues with organizing your code that way.)

The caller default (#3) is really the only way to get optional requirements out of the type system. The weird code path in the compiler here is the same as the weird code path as we have in AnyObject. But it doesn’t look like we’re going to be able to do that.

We can rename this as objcoptional or possibly demote it to an attribute.

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

More information about the swift-evolution mailing list