This week swift-stdlib-tool
was open-sourced, a number of proposals were accepted, Swift releases have themes, and a new proposal for fixing access controls in Swift is now under review!
Sponsored Link
Server-Side Swift
Hello, it’s Paul Hudson from Hacking with Swift again, and after four weeks you’re probably sick of seeing me here. So, I’ll cut to the chase and get out of your way — I wrote a book about Server-Side Swift, and I think you’d like it.
Swift Unwrapped
Episode 3: Source Stability (What is a Source Breaking Change?)
Every Swift developer who has migrated code bases from Swift 1.x to 2.x, or even the more tedious 2.x to 3.x knows the pain of migrating to new Swift versions. In this episode we cover the intricacies of source stability and source-breaking changes. What exactly is a source-breaking change? It’s not as straight-forward as you may think!
News and community
LLVM 4.0.0 was released this week. Congrats to those involved!
Ole Begemann wrote a post, Swift Releases Have Themes, about a thoughtful message from Swift Core Team member Ben Cohen. Ole thinks Ben’s message on swift-evolution deserves more attention, and I agree! It is a couple of weeks old, so sorry for missing this in last week’s issue! 😳 Ole quotes the entire message and provides some commentary. Definitely read this. It’s important for the community to be aware of and help pursue the themes of each Swift release.
Commits and pull requests
In the last couple of issues, we discussed the removal and resurrection of swift-stdlib-tool
. This week, Ted Kremenek made the tool open source!
Manav Gabhawala (@manavgabhawala) opened a pull request that implements a robin hood algorithm for hash collisions in Set
and Dictionary
. It looks like this will improve performance and fix 3 SR issues, although we’re still waiting on benchmark results from the swift-ci bot.
Ankit Aggarwal (@aciidb0mb3r) implemented SE-0158, redesigning the Swift Package Manager API. The API now adheres to the Swift 3 guidelines! 🎉
Accepted proposals
SE-0156: Class and Subtype existentials was accepted.
The proposal was very well-received and is accepted with one modification: the ordering rules for existential types that involve
AnyObject
or aclass
type will be removed.The ordering rules were intended to improve code clarity by requiring that the
class
(orAnyObject
) constraint come first -AnyObject & P
would be well-formed butP & AnyObject
would be an error—enforcing more uniformity for Swift code and echoing a similar restriction that already exists for class definitions, where the superclass must come first. However, the ability to compose typealiases complicated the ordering rules considerably, and - as noted by Matthew Johnson - don’t provide the guarantee that the class constraint will always be first. Therefore, the core team felt that the resulting ordering rules introduced more complexity than they provided clarity, and therefore do not belong in the language.
SE-0157: Support recursive constraints on associated types was accepted.
The feedback on the proposal was unfailingly positive. Accordingly, the proposal has been accepted without further modification.
SE-0158: Package Manager Manifest API Redesign was accepted for Swift 4.
The proposal is accepted with the following revisions:
- The
To
inupToNextMajor
andupToNextMinor
will be capitalized.upToNextMajor()
andupToNextMinor()
will name the first parameterfrom:
for clarity..only
will be removed, as it was duplicative versus.exact
.- We will have cases for
.branch
and.revision
version specifiers, but will not provide special package initializers with named parameters for these.This proposal was generally supported, though it did require some discussion and minor revision, and some users are eager for future proposals adding new API not covered by this proposal.
Proposals in review
SE-0159: Fix Private Access Levels by David Hart is under review.
This proposal presents the problems that came with the the access level modifications in SE-0025 and proposes reverting to Swift 2 behaviour.
Since the release of Swift 3, the access level change of SE-0025 was met with dissatisfaction by a substantial proportion of the general Swift community. Those changes can be viewed as actively harmful, the new requirement for syntax/API changes.
The
private
keyword is a “soft default” access modifier for restricting access within a file. Scoped access is not a good behavior for a “soft default” because it is extremely common to use several extensions within a file. A “soft default” (and thereforeprivate
) should work well with this idiom. It is fair to say that changing the behavior ofprivate
such that it does not work well with extensions meets the criteria of actively harmful in the sense that it subtly encourages overuse of scoped access control and discourages the more reasonable default by giving it the awkward namefileprivate
.[…]
The
private
keyword should be reverted back to its Swift 2 file-based meaning and thefileprivate
keyword should be deprecated.
SE-0160: Limiting @objc
inference by Doug Gregor is under review. Notably, the review manager is Chris Lattner. 😄
One can explicitly write
@objc
on any Swift declaration that can be expressed in Objective-C. As a convenience, Swift also infers@objc
in a number of places to improve interoperability with Objective-C and eliminate boilerplate. This proposal scales back the inference of@objc
to only those cases where the declaration must be available to Objective-C to maintain semantic coherence of the model, e.g., when overriding an@objc
method or implementing a requirement of an@objc
protocol. Other cases currently supported (e.g., a method declared in a subclass ofNSObject
) would no longer infer@objc
, but one could continue to write it explicitly to produce Objective-C entry points.
Mailing lists
As expected, there is a lot of debate in the review of SE-0159: Fix Private Access Levels on the lists. The community is somewhat mixed, but it seems there is mostly strong support for the proposal. As I’ve mentioned before, I strongly support this proposal as well. I think the introduction of fileprivate
(and later, open
) introduced unnecessary complexity in Swift’s access control story for very little tangible benefits. (I’d like to see open
removed as well, but I highly doubt that will happen. 😄)
In support of the proposal, Xiaodi Wu writes:
[…] the proposed solution itself is succinct, unambiguous, and easily understood. It does not argue that the new access level in Swift 3 has no merit, but rather that it has defects sufficient to merit a reversal to what we had before. The migration path is clear and unlikely to cause major problems. Therefore, as I agree with the arguments, I support the proposal.
[…]
However, real-world experience now demonstrates that
fileprivate
is not rarely seen. In fact, as the data above bear out, it is very hard not to usefileprivate
when writing code in at least one very common Swift style (i.e. using same-file extensions). The point is well taken–but in the end it isn’t germane to the argument–that some styles of Swift code do not have to usefileprivate
. The point is that the core team’s acceptance of the design was based on a prediction that did not turn out to be true: namely, that idiomatic Swift would rarely needfileprivate
. As a consequence, more users now have to contend with more access modifiers than anticipated.I disagree that there needs to be much more said about “complexity”–it is self-evident that four access modifiers are more complex than three. (And yes, I agree with previous arguments on this list that only two access modifiers are really necessary at all: internal and public.)
In opposition to the proposal, Matthew Johnson writes:
I am also -1. I think there are two issues to be considered. One is scoped access itself and the other is the names of the access levels.
I think a reasonable case can be made that changing the meaning of private and introducing fileprivate was a mistake. We probably should have left private alone and chosen a new name for scoped access. There was abundant bikeshedding over this at the time, but now we have the benefit of experience. I believe we should have simply called scoped access control
scoped
. It’s clear that some people would still oppose scoped access but I also don’t think we’d be revisiting this topic if we hadn’t changed the meaning ofprivate
. The passionate dislike of the feature seems to me mostly related to stealing theprivate
keyword.I support correcting the naming mistake eventually. I’m neutral as to whether Swift 4 is the right time to do that. We just introduced a lot of churn in Swift 3. There is still inconsistency in Swift’s access control system as well as unmet needs (especially around submodules). It may be better to leave things alone for a release and make the change as part of a larger set of changes when access control and submodules are part of a release “theme”.
I am extremely unconvinced that having a scoped access level is actively harmful. It introduces another choice in the language but no individual programmers or teams are forced to use the additional flexibility if they don’t want to. It would be very easy for linters to prohibit scoped access if there are teams that don’t want to use it. It is one extra degree of control for new programmers to learn but properly taught it helps programmers learn to think about encapsulation. This is a good thing.
[…]
Finally
And finally — move fast and break things. 😏