Saving you thousands of clicks
And finding the highlights and picks
  From the large convolution
  called Swift Evolution
It’s Swift Weekly Brief, sixty-six

The Swift community and core team are pressing on with proposals, pull requests, pitches, and of course posts to the mailing lists about everyone’s favorite topic: access control! 😳

有兴趣赞助 Swift Weekly Brief?点击这里

Swift Unwrapped

Episode 7: Access Control - The Saga Continues

In this week’s episode of Swift Unwrapped, your hosts Messrs. Simard and Squires discuss the roller coaster that is the evolution of access control in Swift: where have we come from, where are we now, and where are we headed in the future? Tune in and become enlightened. 💡

News and community

The Xcode team is pushing on with yet another point release in 8.3.2. Looks like there are a good number of bug fixes and even build time performance improvements (maybe?) 🤔

The master branch of Swift gets merged into the Swift 4.0 branch occasionally, and Swift 4 release manager Ted Kremenek announced the final re-branching date: June 1:

Changes will continue to be pulled into Swift 4 after that date, but the intent is for Swift 4 then to be in gradual convergence and to allow master to incorporate changes that will be included in future releases.

Swift Evolution has a great web dashboard, but as they say on the Internet: is there an app for that? Yes! Check out Evolution App from Thiago Holanda, and you’ll always have Swift access control proposals at your fingertips.

There’s already a new point release of Brisk, the delightful macOS app for submitting radars. Thanks Keith Smiley!

And if you love radars so much, maybe you’re one of the chosen ones selected to try the shiny new Bug Reporter beta? It’s great to see Apple improving its communication channel for developers! 📡

Access Control Pitches

Although I had hoped this section (perhaps this entire issue, even) could be spun off into a separate Swift Access Control newsletter, it looks like that’s not in the cards:

The core team considers the access-control matter closed for Swift 4 and will not be reviewing any further proposals in this area. (source)

Still, this is an issue the community is passionate about getting right and there were some more proposals floated this week:

I think it’s worthwhile to think about what you want and need in terms of access control, and then how to achieve that in current Swift. The matter is closed for now, so we’ll be working with what we have for a while.

Commits and pull requests

SE-0104: Protocol-oriented integers has been implemented! 🎉 Check out the massive pull request for all the history and details.

Along the road to SE-0156: Class and Subtype existentials is combining the concepts of class and AnyObject. As one of the commit messages says: “Soon, Swift.AnyObject will become a protocol composition type with no protocols and a class constraint.”

You’ll find all the details in the “AnyObject removal preparations” pull request. Send @slava_pestov some positive thoughts as you scroll through the massive diff! 😓

Accepted proposals

SE-0161: Smart KeyPaths: Better Key-Value Coding for Swift was accepted.

The meat of this proposal is elevating key paths from plain old strings created safely with #keyPath, to a full type. Aside from the path itself, it could also hold data such as “type, mutability, property name(s), and ability to set/get values.”

This proposal went through a syntax revision to change #keyPath to the lighter weight backslash \, like you’re “escaping” the reference to a property rather than accessing the property directly.

The first review established the main substance of the proposal, while the second review focused mostly on the more lightweight \ syntax.

The core team felt that the leading \ is our best option for introducing keypaths. It is lightweight, yet provides a visual “escape” to indicate that the evaluation of the entities being referenced is being delayed. As noted in the result of the first review, this is part of a longer-term plan to use the \ for unapplied method references, bringing the two closely-related features into syntactic alignment over time and providing an opportunity to stage in the important but currently-source-breaking changes accepted in SE-0042.

There’s already a pull request that includes a skeleton implementation of the standard library API.

SE-0163: String Revision: Collection Conformance, C Interop, Transcoding was accepted with revisions.

A lot of good stuff in this proposal comes from the String Processing For Swift 4 document (formerly known as the Swift String Manifesto). The one change I’m most excited about: strings will conform to BidirectionalCollection and RangeReplaceableCollection! 🎉

SE-0164: Remove final support in protocol extensions was accepted.

I often struggle to explain functions in protocol extensions to Swift newcomers: is it like a superclass implementation? Do you “override” them? How does dispatch work compared to methods defined directly within a type? This proposal removes one confusing bit and disallows the final keyword for functions in protocol extensions.

In the current version of Swift, the final keyword does not modify dispatch behavior in any way, and it does not generate an error message. This keyword has no use in Swift’s current protocol model. Functions in protocol extensions cannot be overridden and will always use direct dispatch.

SE-0168: Multi-Line String Literals was accepted.

As part of the march towards a top-tier Perl-class string processing language, multi-line string literals are coming to Swift! 😉

You’ll be able to use a triple quote """ to open and close string literals. Just be careful about spacing, as “Every line inside the literal must begin with the exact sequence of spaces and tabs that precedes the closing delimiter”:

	"""
	<tab><space>this is OK
	<space><space>this is an error
	<space><tab>this is also an error
	<tab>under-indenting is an error too
	<tab><space><space>but you can go nuts after the indentation all you want
	<tab><space><tab>you do you
	<tab><space>"""

There are plenty of fiddly details, and you should check out the full approval post to read all about them.

SE-0169: Improve Interaction Between private Declarations and Extensions was accepted.

Using the private keyword will now have a slightly wider scope: extensions to a type will be able to access private members declared in the same file.

Same file, same type, need access? private. Same file, different type, need access? fileprivate.

The core team feels that this proposal makes private access align more closely with the goals of the language:

  • It supports the notion that extensions are a code-organization tool: one should be able to break up a type’s definition into several extensions to improve the clarity of that code, without having to open up access or otherwise view the members in different extensions as completely-distinct entities. The core team expects future language evolution to reinforce the notion that extensions are more of a code organization tool than distinct entities, e.g., allowing stored properties to be introduced in an extension.
  • It makes private more usable as the default sub-internal access level, which supports progressive disclosure of the access control system and better matches with programmer’s expectations about what private access means.
  • It makes fileprivate more meaningful, because it is only needed for those cases where one is reaching across types (or among types and globals) within a file. It will also become more rare, which matches well with its longer, descriptive name.

I’m already thinking up alternate names like typefileprivate and reallyprivate. Sorry.

Proposals in review

SE-0170: NSNumber bridging and Numeric types by Philippe Hausler is under review.

NSNumber is a very un-Swifty type: it rolls in all kinds of integer and floating point types into one big type. This proposal suggests ways to clean up the NSNumber bridging and handle underflow and overflow gracefully.

NSNumber has been a strange duck in the Swift world especially when it has come to bridging and interacting with other protocols…as? for NSNumber should mean “Can I safely express the value stored in this opaque box called a NSNumber as the value I want?”.

SE-0171: Reduce with inout by Chris Eidhof is under review.

The reduce method passes along partial results to the next iteration, making copies each time. This proposal suggests adding a “reduce into” variant that uses an inout parameter instead to be more efficient in some cases:

A new variant of reduce should be added to the standard library. Instead of taking a combine function that is of type (A, Iterator.Element) -> A, the full type and implementation of the added reduce will be:

extension Sequence {
    func reduce<A>(into initial: A, _ combine: (inout A, Iterator.Element) -> ()) -> A {
        var result = initial
        for element in self {
            combine(&result, element)
        }
        return result
    }
}

SE-0172: One-sided Ranges by Ben Cohen, Dave Abrahams, and Brent Royal-Gordon is under review.

Currently in Swift, creating a slice of a collection means typing startIndex and endIndex a lot, like s[s.startIndex..<i], or using the prefix and suffix methods.

This proposal introduces the concept of a “one-sided” range, created via prefix/postfix versions of the existing range operators. [The proposed solution is to] introduce a one-sided range syntax, where the “missing” side is inferred to be the start/end:

// half-open right-handed range
let greeting = s[..<i]
// closed right-handed range
let withComma = s[...i]
// left-handed range (no need for half-open variant)
let location = s[i...]

There’s even a work-in-progress diff if you want to see what this might look like in real life.

Mailing lists

Since the mailing lists include folks from many countries and experience levels, it’s important to be precise on what you mean. Here’s a communications pro-tip from core team member Dave Abrahams:

[P]lease don’t use the word “safe” this way around here as it conflicts with the definition used by Swift. As defined by Swift, safety has nothing to do with whether something might trap or whether it’s spelled with a “!”, but about whether it can corrupt memory (source)

To round off this special access control edition of the newsletter, what lessons can we learn from the private vs fileprivate vs the world saga? David Hart suggests a “breeding ground” where we could try out proposed features in real life before making them official.

Javascript has something similar with Babel, which transforms “next generation” Javascript into something that runs in current implementations. The Perl community does something similar, where they often backport Perl 6 features as Perl 5 modules so a wider audience can try them out.

Chris Lattner points out we do have a beta period, in the WWDC-to-September timeline when the vast majority of developers get their hands on official Xcode betas with Swift 4. And is he—core team member and orignal creator of the language—happy with access control?

[I]t remains to be seen, but I strongly believe that we’ve ended up in a good place with access control. The process was painful, but worthwhile to reach a great result.

I like to picture him dropping the mic at this point. 🎤🖐

Finally

I knew type punning was a thing, but Swift nerds take it to a whole other level. 🤣