Welcome to issue #29! This week Xcode 8 beta 2 was released and a lot of proposals were reviewed, accepted, or rejected. There are well over 100 proposals now. It’s hard to believe we’ve seen so many in such a relatively short time!

Commits and pull requests

Patrick Pijnappel refactored UTF8.decode(_:) and UTF16.decode(_:) for speed-ups based on the iterator nil-guarantee introduced in SE-0052. 😎

Harlan Haskins implemented a fixit for a misplaced throws, which corrects func f() -> throws T to func f() throws -> T. 👌

Ankit Agarwal opened a pull request that proposes a method of executing tests in parallel in SwiftPM. 🎉

Josef Willsher implemented proposal SE-0095: Replace protocol<P1,P2> syntax with P1 & P2 syntax. 👏

@practicalswift found two more compiler crashers and added test cases for them. 💥

Accepted proposals

Trent Nadeau’s proposal, SE-0103: Make non-escaping closures the default, was accepted.

The proposal is accepted for Swift 3 with a minor revision: instead of a asUnsafeEscapingClosure(_:) function that removes the @escaping attribute, the core team prefers a function with this signature (roughly) like:

func withoutActuallyEscaping<ClosureType, ResultType>(_ closure: ClosureType, do: (fn : @escaping ClosureType) -> ResultType) -> ResultType {
   // ...
}

This allows one to safely add the @escaping attribute in situations where a closure is known not to actually escape. For example, in a situation where you might want to use a lazy algorithm, you could use:

func yourFunction(fn : (Int) -> Int) {  // fn defaults to non-escaping.
   withoutActuallyEscaping(fn) { fn in  // fn is now marked @escaping inside the closure
   ... somearray.lazy.map(fn)           // pass fn to something that is notationally @escaping
   }
}

The key to this approach is that the withoutActuallyEscaping function can verify that the closure has not actually escaped when it completes, providing a safe model for locally adding the @escaping attribute when needed. The core team believes that the actual implementation of withoutActuallyEscaping will require some magic, but that it should be implementable.

Many thanks to Trent Nadeau for driving this proposal forward. I filed SR-1952 to track implementation of this feature.

Joe Groff’s proposal, SE-0102: Remove @noreturn attribute and introduce an empty Never type, was accepted.

The core team accepted the proposal for Swift 3 with a revision to change the name of the type from “NoReturn” to “Never”.

The feedback on the proposal was generally very positive from the community. The only significant concern was from people who felt that merging the concept of “does not return” into the result type of the function conflates two concepts. The core team feels that unifying these concepts overall reduces the surface area of the language by eliminating an obscure (but important) type system concept outright.

The other significant discussion was about the actual name for the “NoReturn” type. The core team enjoyed the community idea of naming it “💥” or ”🔃” but decided that the name lacked clarity. Ultimately the core team agreed with the loud voice of the community that “Never” is the right name for this type.

Thank you to Joe Groff for driving this proposal forward! I filed SR-1953 to track implementation of this feature.

Proposal SE-0104: Protocol-oriented integers from Dave Abrahams, Dmitri Gribenko, and Maxim Moiseev, was accepted.

The feedback from the community was very positive and contributed a number of improvements to the design of the proposal. The core team has accepted the proposal, subject to the following changes:

  • The Integer protocol should be renamed to BinaryInteger to be more accurate and avoid confusion between Int and Integer.
  • The FloatingPoint protocol should conform to the Arithmetic protocol.
  • Rename the absoluteValue property to magnitude, and sink it down to the Arithmetic protocol.
  • Eliminate the AbsoluteValuable protocol, since abs can now be defined in terms of Arithmetic.
  • Rename the signBitIndex property to minimumSignedRepresentationBitWidth.
  • Add a popcount property requirement to the FixedWidthInteger protocol.
  • Change the countLeadingZeros() member of concrete types to be a leadingZeros property on FixedWidthInteger.
  • Rename func nthWord(n: Int) -> UInt to func word(at: Int) -> UInt.
  • Rename the and, or, and xor members of FixedWidthInteger to bitwiseAnd, bitwiseOr and bitwiseXor.
  • Change doubleWidthMultiply to be a static member, and add a doubleWidthDivide member as its dual. The latter will return both quotient and remainder of type Self. Both are to be added to the FixedWidthInteger protocol.

Many thanks to Maxim Moiseev, Dave Abrahams and Dmitri Gribenko for driving this proposal forward, Steve Canon for his important input, and to Maxim Moiseev for driving the implementation work forward.

Vladimir S. and Austin Zheng’s proposal, SE-0110: Distinguish between single-tuple and multiple-argument function types, was reviewed and accepted.

The community and core team agree that this proposal is the right thing to do, and many agree that this could probably have been treated as a bug fix on a previous proposal.

Thank you to Vladimir S. and Austin Zheng for driving this discussion forward! I filed SR-2008 to track implementation work on this, this would be a great area for someone interested in the type checker to dive into the Swift compiler.

SE-0110 proposal summary:

Swift’s type system should properly distinguish between functions that take one tuple argument, and functions that take multiple arguments. Right now, the following is possible:

let fn1 : (Int, Int) -> Void = { x in
   // The type of x is the tuple (Int, Int)
}

let fn2 : (Int, Int) -> Void = { x, y in
   // The type of x is Int, the type of y is Int
}

Austin Zheng’s proposal, SE-0111: Remove type system significance of function argument labels, was reviewed and accepted.

The community and core team agree that this proposal will lead to a simplification and clarification of the type system, as well as a more clear user model for parameter labels. In response to community feedback, the core team is accepting the proposal with a revision to allow “purely cosmetic” parameter labels in closure types for documentation (as outlined in the alternatives section). The core team also wants to clarify that a call to a value of closure type would not allow use of any parameter labels, some interpretations thought that “arbitrary” parameter labels could be used.

Thank you to Austin Zheng for driving this discussion forward! I filed SR-2009 to track implementation work on this.

SE-0111 proposal summary:

Swift’s type system should not allow function argument labels to be expressed as part of a function type.

Right now, argument labels are considered significant by the type system, and the type system establishes subtyping relationships between function types with and without argument labels. Here is an example:

func doSomething(x: Int, y: Int) -> Bool {
   return x == y
}

let fn1 : (Int, Int) -> Bool = doSomething
// Okay
fn1(1, 2)

// fn2's type is actually (x: Int, y: Int) -> Bool
let fn2 = doSomething

// Okay
fn2(x: 1, y: 2)
// NOT ALLOWED
fn2(1, 2)

As currently implemented, this feature can lead to surprising behavior. Removing this feature simplifies the type system. It also changes the way argument labels are treated to be consistent with how default arguments are treated; that is, tied to a declaration and not part of the type system.

Karl Wagner’s proposal, SE-0113: Add integral rounding functions to FloatingPoint, was reviewed and accepted.

The community and core team agree that this proposal helps to “round out” the other Swift 3 numerics work. One minor revision is necessary to make the proposal implementable in Swift 3. Since protocol requirements cannot currently have default arguments, the desired behavior should be achieved with two overloads of each operation:

protocol FloatingPoint {
   /// Returns a rounded representation of `self`, according to the specified rounding rule.
   func rounded() -> Self
   func rounded(_ rule: RoundingRule) -> Self

   /// Mutating form of `rounded`.
   mutating func round()
   mutating func round(_ rule: RoundingRule)
}

Where the no argument cases can be implemented with a protocol extension that forwards to the single-argument versions. Thank you to Karl Wagner for driving this discussion forward! I filed SR-2010 to track implementation work on this.

SE-0113 proposal summary:

The standard library lacks equivalents to the floor() and ceil() functions found in the standard libraries of most other languages. Currently, we need to import Darwin or Glibc in order to access the C standard library versions.

Rejected proposals

Proposal SE-0105: Removing Where Clauses from For-In Loops was rejected.

The vast majority of the community of the community prefers to keep this language feature, and the core team agrees. Even though ‘where’ is a small bit of syntactic sugar, it improves the expressivity (therefore readability and maintainability) of important loops.

Many thanks to Erica Sadun for driving this discussion and writing the proposal. This proposal was important and fit with an important goal of Swift 3, which is to re-evaluate all of the existing language features to make sure they are a good for the language over the long term.

Proposal SE-0108: Remove associated type inference was rejected.

The community and core team agree that removing this feature will impose an unacceptable user experience regression for developers using Swift generics, including important protocols like Collection. While we all seek the simplifications to the compiler internals that the proposal would allow, we will have to consider other approaches to achieving that in subsequent releases.

Thank you to Douglas Gregor and Austin Zheng for driving this discussion forward!

Returned proposals

Proposal SE-0101: Reconfiguring sizeof and related functions into a unified MemoryLayout struct was returned for revision.

The proposal is returned for revision, with the goal for a revised version to make it into Swift 3. The thread discussing it has already turned towards new ways to express these ideas, so when that thread runs its course we’ll restart review of the revised proposal.

Proposal SE-0091: Improving operator requirements in protocols was returned for revision.

While many people were positive about improving lookup of operators, several concerns about introduction of boilerplate were raised. Tony and Doug have discussed it further and plan to revise and resubmit the proposal for another round of review.

Proposals in review

Doug Gregor’s and Charles Srstka’s proposal, SE-0112: Improved NSError Bridging, is under review.

Swift bridges between ErrorProtocol-conforming types and NSError so, for example, a Swift enum that conforms to ErrorProtocol can be thrown and will be reflected as an NSError with a suitable domain and code. Moreover, an NSError produced with that domain and code can be caught as the Swift enum type, providing round-tripping so that Swift can deal in ErrorProtocol values while Objective-C deals in NSError objects.

However, the interoperability is incomplete in a number of ways, which results in Swift programs having to walk a careful line between the ErrorProtocol-based Swift way and the NSError-based way. This proposal attempts to bridge those gaps.

Erica Sadun’s proposal, SE-0114: Updating Buffer “Value” Names to “Header” Names, is under review.

This proposal updates parameters and generic type parameters from value names to header names for ManagedBuffer, ManagedProtoBuffer, and ManagedBufferPointer.

All user-facing Swift APIs must go through Swift Evolution. While this is a trivial API change with an existing implementation, this formal proposal provides a paper trail as is normal and usual for this process.

Matthew Johnson’s proposal, SE-0115: Rename Literal Syntax Protocols, is under review.

This proposal renames the *LiteralConvertible protocols to ExpressibleAs*Literal.

The standard library currently has protocols that use the term Convertible in two different ways. The *LiteralConvertible protocols use the meaning of converting from a literal. The Custom(Debug)StringConvertible protocols use the meaning of converting to a String. This causes confusion for developers attempting to name their own protocols following the precedence established by the standard library.

Joe Groff’s proposal, SE-0116: Import Objective-C id as Swift Any type, is under review.

Objective-C interfaces that use id and untyped collections should be imported into Swift as taking the Any type instead of AnyObject.

Objective-C’s id type is currently imported into Swift as AnyObject. This is the intuitive thing to do, but creates a growing tension between idiomatic Objective-C and Swift code. One of Swift’s defining features is its value types, such as String, Array, and Dictionary, which allow for efficient mutation without the hazards of accidental state sharing prevalent with mutable classes. To interoperate with Objective-C, we transparently bridge value types to matching idiomatic Cocoa classes when we know the static types of method parameters and returns. However, this doesn’t help with polymorphic Objective-C interfaces, which to this day are frequently defined in terms of id. These interfaces come into Swift as AnyObject, which doesn’t naturally work with value types. To keep the Swift experience using value types with Cocoa feeling idiomatic, we’ve papered over this impedance mismatch via various language mechanisms…

Proposal SE-0118: Closure Parameter Names and Labels from Dave Abrahams, Dmitri Gribenko, and Maxim Moiseev is under review.

We propose a revision to the names and argument labels of closure parameters in standard library APIs.

The names and argument labels of the standard library’s closure parameters have been chosen haphazardly, resulting in documentation comments that are inconsistent and often read poorly, and in code completion/documentation that is less helpful than it might be. Because of trailing closure syntax, the choice of argument labels for closures has less impact on use-sites than it might otherwise, but there are many contexts in which labels still do appear, and poorly-chosen labels still hurt readability.

Javier Soto’s and John McCall’s proposal, SE-0117: Default classes to be non-subclassable publicly, is under review.

Since Swift 1, marking a class public provides two different capabilities: it allows other modules to instantiate and use the class, and it also allows other modules to define subclasses of it. This proposal suggests splitting these into two different concepts. This means that marking a class public allows the class to be used by other modules, but does not allow other modules to define subclasses. In order to subclass from another module, the class would be marked subclassable.

Relatedly, Swift also conflates two similar concepts for class members (methods, properties, subscripts): public means that the member may be used by other modules, but also that it may be overriden by subclasses. This proposal introduces a new overridable modifier, which is used instead of public on members that are overridable.

Finally

And finally — “Could you write me a nice reference letter?”