Holocene and heard: What’s up in Swift Evolution

Accepted

SE-0089: Renaming String.init<T>(_: T) is accepted. Team writes:

The second review of SE-0089: “Renaming String.init<T>(_: T)” ran from June 4…7. The proposal is *accepted* for Swift 3.

The feedback from the community on this second round was light, which indicates that the extensive iteration on earlier rounds brought this to a good place. The core team discussed other possibilities for the parameter label (e.g. from: instead of describing:) but ended up agreeing that a more explicit “describing:” label is the best fit for this API.

SE-0106: Add a macOS Alias for the OSX Platform Configuration Test is accepted. Team writes:

The core team is proactively accepting SE-0106 “Add a macOS Alias for the OSX Platform Configuration Test” without a formal review, under the rationale that the proposal is “obvious” and probably should have been treated as a bug fix. Adding aliases for other uses of “OS X” in the language to use macOS are also proactively accepted.

SE-0095: Replace protocol<P1,P2> syntax with P1 & P2 syntax is accepted. “The current protocol<> construct, which defines an existential type consisting of zero or more protocols, should be replaced by an infix & type operator joining bare protocol type names.” Team writes:

This syntax has been extensively discussed by the community, and is a cornerstone of the “generalized existentials” work for future Swift releases.  The community was overall positive on the feature with a few subjective concerns about “&” being tightly associated with bitwise logical operations.  The core team believes this will not be contextually confusing since it appears in a type position, between two names that are obviously nominal types (e.g. they are capitalized).

I filed SR-1938 to track implementation of this work, this is a somewhat advanced starter project which would be a great place for someone to dive into the parsing logic in Swift.

SE-0104: Protocol-oriented integers is accepted with revisions. “This proposal cleans up Swifts integer APIs and makes them more useful for generic programming. The way the Arithmetic protocol is defined, it does not generalize to floating point numbers and also slows down compilation by requiring every concrete type to provide an implementation of arithmetic operators as free functions, thus polluting the overload set. Converting from one integer type to another is performed using the concept of the ‘maximum width integer’ (see MaxInt), which is an artificial limitation. Another annoying problem is the inability to use integers of different types in comparison and bit-shift operations.” Team writes:

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.

SE-0102: Remove @noreturn attribute and introduce an empty NoReturn type is accepted. “We should remove the rarely-used @noreturn function type attribute and instead express functions that don’t return in terms of a standard uninhabited type.” Team writes,

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.

SE-0103: Make non-escaping closures the default is accepted with a minor revision. “This proposal switches the default to be non-escaping and requires an @escaping annotation if a closure argument can escape the function body. Since the escaping case can be statically detected, this annotation can be added via an error with a fixit. Other annotations that have consequences for escape semantics (e.g., @autoclosure(escaping)) will be altered to make use of the new @escaping annotation.” Team writes:

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.

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.

Returned for Revision

SE-0077: Improved operator declarations is returned for revisions. The team writes:

On June 22, 2016, the core team decided to return the first version of this proposal for revision. The core design proposed is a clear win over the Swift 2 design, but feels that revisions are necessary for usability and consistency with the rest of the language:

  • The proposed associativity(left) and precedence(<) syntax for precedence group attributes doesn’t have a precedent elsewhere in Swift. Furthermore, it isn’t clear which relationship < and > correspond to in the precedencesyntax. The core team feels that it’s more in the character of Swift to use colon-separated “key-value” syntax, with associativitystrongerThan, and weakerThan keyword labels:
      precedencegroup Foo {
        associativity: left
        strongerThan: Bar
        weakerThan: Bas
      }
  • If “stronger” and “weaker” relationships are both allowed, that would enable different code to express precedence relationships in different, potentially confusing ways. To promote consistency and clarity, the core team recommends the following restriction: Relationships between precedence groups defined within the same module must be expressedexclusively in terms of strongerThanweakerThan can only be used to extend the precedence graph relative to another module’s groups, subject to the transitivity constraints already described in the proposal. This enforces a consistent style internally within modules defining operators.
  • The proposal states that precedence groups live in a separate namespace from other declarations; however, this is unprecedented in Swift, and leads to significant implementation challenges. The core team recommends that precedence groups exist in the same namespace as all Swift declarations. It would be an error to reference a precedence group in value contexts.
  • Placing precedence groups in the standard namespace makes the question of naming conventions for precedencegroup declarations important. The core team feels that this is an important issue for the proposal to address. As a starting point, we recommend CamelCase with a -Precedence suffix, e.g. AdditivePrecedence. This is unfortunately redundant in the context of a precedencegroup declaration; however, precedencegroups should be rare in practice, and it adds clarity at the point of use in operator declarations in addition to avoiding naming collisions. The standard library team also requests time to review the proposed names of the standard precedence groups
  • This proposal quietly drops the assignment modifier that exists on operators today. This modifier had one important function–an operator marked assignment gets folded into an optional chain, allowing foo?.bar += 2 to work as foo?(.bar += 2) instead of (foo?.bar) += 2. In practice, all Swift operators currently marked assignment are at the Assignment precedence level, so the core team recommends making this optional chaining interaction a special feature of the Assignment precedence group.
  • This proposal also accidentally includes declarations of &&= and ||= operators, which do not exist in Swift today and should not be added as part of this proposal.

SE-0091: Improving operator requirements in protocols is returned for revision. “When a type conforms to a protocol that declares an operator as a requirement, that operator must be implemented as a global function defined outside of the conforming type. This can lead both to user confusion and to poor type checker performance since the global namespace is overcrowded with a large number of operator overloads. This proposal mitigates both of those issues by proposing that operators in protocols be declared statically (to change and clarify where the conforming type implements it) and use generic global trampoline operators (to reduce the global overload set that the type checker must search).” Team writes:

The review of “SE-0091: Improving operator requirements in protocols” ran from May 17…23.  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.

 

SE-0101: Rename sizeof and related functions to comply with API Guidelines is returned for revision. “Upon accepting SE-0096, the core team renamed the proposed stdlib function from dynamicType() to type(of:) to better comply with Swift’s API guidelines. This proposal renames sizeofsizeofValuestrideofstrideofValuealign, and alignOf to emulate SE-0096’s example.” This one has a major alternative redesign being crafted. Team writes:

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.

Rejected

SE-0105: Removing Where Clauses from For-In Loops is rejected. “This proposal removes where clauses from for-in loops, where they are better expressed (and read) as guard conditions.” Expect a rejection on this very unpopular proposal but the team may adopt some of the alternatives considered for better language consistency. Team writes:

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.

In Review

  • May 9…16 SE-0086: Drop NS Prefix in Swift Foundation “As part of Swift 3 API Naming and the introduction of Swift Core Libraries, we are dropping the NS prefix from key Foundation types in Swift.”
  • June 28 … July 4 SE-0107: UnsafeRawPointer API “Swift enforces type safe access to memory and follows strict aliasing rules. However, code that uses unsafe APIs or imported types can circumvent the language’s natural type safety.” This extensive redesign addresses many issues under the microscope.
  • June 28 … July 4 SE-0109: Remove the Boolean protocol “For legacy and historical reasons Swift has supported a protocol named Boolean for abstracting over different concrete Boolean types. This causes problems primarily because it is pointless and very confusing to newcomers to Swift: is quite different than Bool, but shows up right next to it in documentation and code completion. Once you know that it is something you don’t want, you constantly ignore it. Boolean values are simple enough that we don’t need a protocol to abstract over multiple concrete implementations.”
  • SE-0077 v2: Improved operator declarations in 2nd review to 7/4. (1st version) “Replace syntax of operator declaration, and replace numerical precedence with partial ordering of operators” However many reviews it takes, this is a good one to get right.
  • SE-0111: Remove type system significance of function argument labels in review to 7/4. “Swift’s type system should not allow function argument labels to be expressed as part of a function type. 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”
  • SE-0110: Distinguish between single-tuple and multiple-argument function types in review to 7/4. “Swift’s type system should properly distinguish between functions that take one tuple argument, and functions that take multiple arguments. The current behavior violates the principle of least surprise and weakens type safety, and should be changed.”
  • SE-0108: Remove associated type inference in review to 7/4. “The main advantage of removing associated type witness inference is that it decreases the complexity of the type checker. Doing so removes the only aspect of Swift that depends upon global type inference. Simplifying the type checker makes it easier to improve the performance and correctness of the type checker code. Given that both are widely acknowledged issues with current versions of Swift, any opportunity for improvement should be carefully considered.”
  • SE-0112: Improved NSError Bridging in review to 7/4. “Swift’s error handling model interoperates directly with Cocoa’s NSError conventions. For example, an Objective-C method with an NSError** parameter will be imported as a throwing method. This proposal introduces new protocols and a different way of bridging Objective-C error code types into Swift, along with some conveniences for working with Cocoa errors.”
  • SE-0114: Updating Buffer “Value” Names to “Header” Names in review to 7/7. “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.”
  • SE-0115: Rename Literal Syntax Protocols in review to 7/7. “This proposal renames the *LiteralConvertible protocols to ExpressibleAs*Literal.”

Scheduled

Nothing right now

Not Yet Scheduled

Comments are closed.