Quite a lot of work has been done to implement recently accepted Swift Evolution proposals, as well as improving their diagnostics and error messages. Interestingly, some of this work has been done by first-time contributors, which is amazing to see!

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

Swift Unwrapped

Episode 9: String Manifesto

This week JP Simard and Jesse Squires discuss the String Manifesto!

Commits and pull requests

Slava Pestov implemented SE-0156: Class and Subtype existentials.

Brent Royal-Gordon opened a pull request to improve diagnostics for multi-line string literals (SE-0168).

Brian King implemented SE-0169: Improve Interaction Between private Declarations and Extensions. 🚀

Robert Widmann has redone exhaustiveness checking, fixing a lot of SR-bugs in the process.

Accepted proposals

SE-0170: NSNumber bridging and Numeric types was accepted for Swift 4.

SE-0173: Add MutableCollection.swapAt(_:_:) was accepted with revisions and has also been implemented.

The proposal is accepted, including the revision to change the method name from swap(_:with:) to swapAt(_:_) that came out of the Core Team meeting.

The consensus on swift-evolution was to add the method, with division mostly on the naming of the method. The Core Team reviewed the proposed options as well as consulted the API design guidelines to resolve the issue.

Two important points from the guidelines serve to us well here:

“Omit all labels when arguments can’t be usefully distinguished”

and:

“When the first argument forms part of a prepositional phrase, give it an argument label… An exception arises when the first two arguments represent parts of a single abstraction. In such cases, begin the argument label after the preposition, to keep the abstraction clear.”

The combination of these rules leads to the method name swapAt(_:_:), which the Core Team believes was most in line with the guidelines.

SE-0176: Enforce Exclusive Access to Memory by John McCall is under review.

In Swift 3, it is possible to modify a variable while it’s being used or modified by another part of the program. This can lead to unexpected and confusing results. It also forces a great deal of conservatism onto the implementation of the compiler and the standard libraries, which must generally ensure the basic soundness of the program (no crashes or undefined behavior) even in unusual circumstances.

We propose that Swift should instead enforce a general rule that potential modifications of variables must be exclusive with any other access to that variable.

Proposals in review

SE-0174: Change filter to return an associated type by Ben Cohen is under review.

This proposal changes the filter operation on Sequence to return an associated type, and adds a default implementation to RangeReplaceableCollection to return the same type as the filtered collection.

The recently accepted SE-0165 introduced a version of filter on Dictionary that returned a Dictionary. This had both performance and usability benefits: in most cases, a Dictionary is what the user wanted from the filter, and creating one directly from the filter operation is much more efficient than first creating an array then creating a Dictionary from it.

However, this does result in some inconsistencies. Users may be surprised that this one specific collection returns Self, while other collections that would benefit from the same change still return [Element]. And some collections, such as String, might also benefit from usability and performance win similar to Dictionary. Additionally, these wins will be lost in generic code – if you pass a Dictionary into an algorithm that takes a Sequence, then when you filter it, you will still get an Array.

SE-0175: Package Manager Revised Dependency Resolution by Rick Ballard is under review.

This proposal makes the package manager’s dependency resolution behavior clearer and more intuitive. It removes the pinning commands (swift package pin & swift package unpin), replaces the swift package fetch command with a new swift package resolve command with improved behavior, and replaces the optional Package.pins file with a Package.resolved file which is always created during dependency resolution.

Mailing lists

There has once again been some discussion around Optional, throws and the Result type. Although we probably won’t see changes here in the near future, it’s interesting to see this keeps resurfacing and the ideas maturing.

Doug Gregor writes:

[..] the current error-handling system will not be going away, for the reasons Jaden has stated above.

Maybe we will grow typed throws at some point; maybe Result will get added to the standard library with some nice affordances to map between throwing and Result-producing types; but we’re well beyond the point where we can rip out major features that have been generally well-received.

In the earlier discussion on revamping Optional and throws, John McCall writes:

We’ve definitely considered including a Result type, but our sense was that in an ideal world almost no code would be using it. It’s hard to imagine an ordinary API that ought to be returning a Result rather than throwing, and once you’ve defined that away, the major remaining use case is just to shift computation around, like with a completion handler. That explicit computation-shifting pattern is something we’re hoping to largely define away with something like C#’s async/await, which would leave Result as mostly just an implementation detail of such APIs. We didn’t want to spend a great deal of time designing a type that would end up being so marginal, especially if the changing role would lead us into different directions on the design itself. We also didn’t want to design a type that would become an obstacle to potential future language changes like, say, typed throws.

The downside, of course, is that as long as we lack that async/await design, computation-shifting isn’t real great.

Finally

And finally — Xcode might not be as genius as you think. 🤔