Issue #31 21 Jul 2016
Written by: Jesse Squires
Welcome to issue #31! Beta 3 of Xcode and all the platforms are now available. The most important news this week was Ted Kremenek’s email on the endgame for Swift 3 (see below). The last day for Swift 3 breaking changes is July 27, and discussions on Swift 4 will begin August 1. Moving fast! 😱
- SR-1266: Fix duplication of
validation-test. This starter task is from April, but it continues to cause pain for Swift compiler developers today. The goal of this task is to make it easier for developers to modify the variables being passed to the Swift test suite – developers currently need to modify two files in two different parts of the codebase. Completing this task would reduce that down to just one file. Basic knowledge of Python would be helpful in completing this task, but is not necessary.
- SR-2117: Add documentation for SourceKit request types. SourceKit has a lot of functionality that could be very useful when building developer tools for Swift, but very little documentation on how to use those tools. The goal for this task is to use SourceKit, see what it does, and document its behavior. Being able to read the C++ source code for SourceKit would help, but is not required.
Brian Gesiak has hacked together Swift support for the Nuclide IDE! 🤓 It’s still a work-in-progress and you couldn’t replace Xcode yet, but if you’re looking for a Swift IDE on Linux, this will be ready soon. 👌
Commits and pull requests
There was very sparse commentary, and all of it was positive. The core team believes this is an “obvious” proposal.
Thank you to Arnold Schwaighofer for proposing this cleanup!
There was very sparse commentary, and all of it was positive. The one requested change from the discussion is to remove
@discardableResult, which has already been made to the proposal.
Thank you to Lorenzo Racca, Jeff Hajewski, and Nate Cook for proposing this cleanup!
The proposal has been accepted, pending more implementation experience: This proposal was very positively received by the community, and garnered a lot of feedback (which has already been incorporated into the proposal). This proposal has significant implementation complexity, but the work to build it is nearing completion. When this lands, there is some risk that we’ll need to revise the design in small ways due to unanticipated effects, but the core team believes it is the right overall design to aim for.
Thank you to Joe Groff for driving the design and discussion around this feature, as well as many people who are contributing to the implementation and design effort.
The proposal has been accepted, with a revision to change
enumwith no cases. The overall feedback was very positive. The core team did discuss a proposal to move the generic type to each member, but felt that that would increase the verbosity of using the API (since
T.selfwould be required) and would lead to possible confusion in the API (because it wouldn’t be clear whether you were asking for the size of a type, or the size of its metatype).
Thank you to Erica Sadun and Dave Abrahams for driving this discussion forward.
Feedback has been universally positive from both the community and the core team, because it eliminates a surprising part of the Swift model at very little utility cost.
Thank you to Jacob Bandes-Storch for driving this discussion forward.
Proposal SE-0117: Default classes to be non-subclassable publicly from Javier Soto and John McCall was returned for revision. The proposal then had a second review, after which it was returned for revision again. 😄
From the first return:
As expected, this proposal was extremely polarizing, with valid arguments on both sides. The opinions held by supporters and opposers are held very strongly, and hundreds of emails were generated in a healthy debate about this topic.
The review manager read every post on this topic, and the core team discussed this topic at length. The core team concluded three things:
- First, the core team agrees with conviction that it is the right default for public classes to be non-subclassable outside their module, unless they carry some additional indication from the API author that the class was designed to be subclassed.
- Second, there was insufficient discussion about anything other than the first point. The proposal also contains the “overridable” concept, which is highly impactful, but lacked significant discussion.
- Third, the core team agrees that the concrete syntax of “subclassable class” is … suboptimal.
On the first point, there are three related arguments against SE-0117:
- First is that clients of Apple frameworks often choose to subclass classes that Apple publicly documents as being “not for subclassing”, as a way of “getting their job done,” typically as a way to work around claimed bugs in Apple frameworks. The core team and others at Apple feel that this argument is analogous to the argument that Swift should “support method swizzling by default”. Swift loves dynamic features, but has already taken a stance against unanticipated method swizzling, by requiring an API author to indicate where they allow method swizzling with the ‘dynamic’ keyword. Almost all classes vended by Apple APIs are subclassable (which isn’t changed by this proposal) so this argument is not compelling to the core team, nor is it consistent with the existing design of Swift. It is also important to note that Cocoa also makes heavy use of delegation (via protocols) which allows client code to customize framework behavior without subclassing.
- Third is a longer-term meta-concern, wherein a few people are concerned that future pure-Swift APIs will not consider subclass-ability in their design and will accidentally choose-by-omission to prevent subclass-ability on a future pure-Swift API (vended by Apple or otherwise). The core team feels that this is an extremely unlikely situation for several reasons. First of which is that it heavily overlaps the first two concerns. More significantly, any newly-designed and from-scratch APIs that are intended for Swift-only clients will make use of a breadth of abstractions supported by Swift—structs, enums, protocols, classes. The primary reasons to use classes in Swift are subclassability and reference semantics, so the core team feels that the likelihood of accidental omission is small. Likewise, the decision to require every member of a public class to be marked public in Swift indicates a commitment (in line with SE-0117) that expects cross-module API authors to think carefully about the API they are authoring as well as their use cases.
To reiterate, as a summary, the core team agrees with conviction that it is the right default for public classes to be non-subclassable outside their module, unless they carry some additional indication by the API author that the class was designed to be subclassed. However, it does not yet have an opinion as to what that concrete syntax is.
To sum this all up, the core team is rejecting this proposal and requesting a revision to change the concrete syntax to
public open class Fooinstead of
subclassable class Foo. This approach satisfies the unwavering goal of requiring additional thought when publishing a class as public API, makes subclass-ability orthogonal to access control, and (admittedly as a bit of a swift-evolution process hack) asks the community for an in-depth discussion of the secondary points of the proposal: does it make sense to require every member to be marked as
overridablein order to be overridden by an open subclass outside of the current module?
The core team appreciates that this is a situation where it is impossible to please everyone, while also recognizing that the challenges faced by developers of pure-Swift code are not exactly analogous to those faced by Objective-C developers. Thank you to the many and diverse opinions and perspectives that have come in as part of this review cycle!
From the second return:
As with the first round of discussion, the community generated a large number of emails, exploring the various aspects of the proposal. While many community members agree with the thrust of the proposal, a number of people are concerned with the boilerplate being introduced by the proposal, among other issues. The core team spent over two and a half hours discussing this topic from first principles, and has come up with a similar-but-different approach that should reduce the boilerplate, while still accomplishing the primary aims of the proposal. John McCall will be revising the proposal today and we’ll restart a short discussion period about it tomorrow.
Thank you to Javier Soto and John McCall for driving this discussion forward.
The majority of the feedback on this proposal was opposed to it. While the goal of the proposal is laudable, SE-0121 eliminated the most surprising problem that this proposal aimed to address, and the rest of it (notably the
??operator) can be addressed in other ways in the Swift 3 timeframe. The core team recommends that the
??case be handled by having the compiler produce a warning when the left side of the
??operator is implicitly promoted to optional. In the post-Swift 3 timeframe, we can investigate other broader options for solving this problem more generally (e.g. a new parameter attribute).
Thank you to Mark Lacey, Doug Gregor, and Jacob Bandes-Storch for driving this discussion forward.
Proposals in review
Proposal SE-0122: Use colons for subscript declarations from James Froggatt is under review. Currently, subscripts have the form:
subscript(param: P) -> ElementType. James argues that the similarities between subscript and function declarations can cause confusion.
The arrow, borrowed from function syntax, is very much out of place in this context, and so can act as a mental stumbling block. It is also misleading, as it implies that subscripts have the full capabilities of functions, such as the ability to throw. If throwing functionality were to be added to accessors, it is likely the specific get/set accessor would be annotated. In this case, the effects on a subscript’s ‘function signature’ could become a source of confusion.
Subscripts act like parameterised property accessors. This means, like a property, they can appear on the left hand side of an assignment, and values accessed through subscripts can be mutated in-place. The colon has precedent in declaring this kind of construct, so it makes sense to reuse it here.
isUniquelyReferenced<T: NonObjectiveCBase>(_ object: T).
isUniquelyReferencedcan be replaced by
isUniquelyReferencedNonObjC<T: AnyObject>(_ object: T). This replacement is as performant as the call to
isUniquelyReferencedin cases where the compiler has static knowledge that the type of
objectis a native Swift class and dyamically has the same semantics for native swift classes. This change will remove surface API.
This proposal wants to revise metatypes
T.Type, repurpose public
T.selfnotation to return a new
Type<T>type instance rather than a metatype, merge SE-0101 into
Type<T>, rename the global function from SE-0096 to match the changes of this proposal and finally rename current
Mirrortype to introduce a new (lazy)
This proposal deals with three routines and one class related to pointers and buffers. The goal of this proposal is to update the API to match new API guidelines and remove redundant identifiers.
The stdlib has been thoroughly updated to follow the new API guidelines and these are the few places that need to be updated in pointer and buffer APIs…
Ted Kremenek sent an email on the endgame for Swift 3, highlighting the development plans for the release and the proposals that have not yet been completed.
Swift 3 has shaped up to be a remarkable release — a product of the inspiration, ideas, and hard labor many people from across the Swift open source community. It is now time, however, to talk about the endgame for the release.
Here are the key points:
The last day to take planned source-breaking changes for Swift 3 is July 27.
On that day, there will likely be a set of approved-but-not-implemented proposals for Swift 3 — including proposals for source-breaking changes. Will have an open discussion on that day on the fate of those unimplemented proposals in the context of Swift 3 and future Swift releases.
Starting on August 1 we will open up discussion about Swift 4. Part of this discussion will likely be guided by important work that was deferred from Swift 3, as well as the a goal of achieving binary stability in Swift 4. Until then, however, discussion should remain focused on Swift 3.
Note that there is an intentional gap of a few days between the last planned day to take source-breaking changes for Swift 3 and when we start talking about Swift 4. The idea is to provide some time for the community to take stock of where things have ended up for Swift 3.
The final branching plan for Swift 3 development is to be determined, but the final convergence branch is likely to be cut from master around that date or shortly after. Part of it comes down to the discussion on July 27 on how to handle the remaining unimplemented proposals for Swift 3.
The final release date for Swift 3 is TBD, but essentially after July 27 the intent is that Swift 3 is in full convergence and not in active development.
With these dates in mind, I want to call attention to some approved-but-not-yet-implemented proposals that currently I have nobody on Apple’s Swift team able to tackle in the next couple weeks: …
And finally — “We still love you George, even if we forgot your e.” 😄
(If you aren’t familiar, this is a reference to George Boole.)