Another two weeks have passed in the blink of an eye. I’ve been busy launching my new project into the wild, listening to critical feedback from early users, and doing my best to improve it.

Jeroen Leenarts and I teamed up to improve the mailing list platform we’re using to send out this newsletter, and hopefully to cut costs. This week is the first real test. If this email finds your mailbox, then we know it’s working. :)

I want to thank all the supporters, sponsors and everyone in the Swift community who help make this project happen. If you have any ideas about things to change, improve upon, or help support this newsletter financially, please let me know.

Without further ado, we have some great news this time!

Podcasts

In episode 92 of the Swift by Sundell podcast, Kaitlin Mahar joins John Sundell to discuss the current state of server-side Swift, designing APIs for server-side libraries, and Swift’s upcoming suite of structured concurrency features.

News and community

Adam Fowler wrote a blog post about Hummingbird: A Swift HTTP server framework. Hummingbird is a lightweight, flexible server framework. It is split into three sections: HummingbirdCore, the HTTP server; Hummingbird, the web application framework; and finally the extension modules.

Dave DeLong wrote a great article talking about exploiting String interpolation for fun and profit.

Tibor Bödecs wrote an article explaining memory layout in Swift.

Commits and pull requests

Slava Pestov merged a pull request that adds a new algorithm for identifying redundant non-same-type requirements.

Kavon Farvardin merged a pull request that allows get access to properties from outside the actor.

Victor Guerra merged a pull request that improves diagnostics for when a registered derivative function differs from the function it derived from.

Accepted proposals

SE-0299: Extending Static Member Lookup in Generic Contexts was accepted with modifications.

The second review period for SE-0299: Extending Static Member Lookup in Generic Contexts has concluded. The core team has decided to accept this revision proposal, with one more modification suggested by John McCall:

I’m somewhat happy with the new restriction requiring a Self constraint, but I’m worried that making that unconditional is going to be unnecessarily limiting on the case where you’re just building a value of protocol type. Or does that not work because we don’t know what to bind Self to?

I would suggest the rule that the variable type / function return type should be required to be a subtype of the Self type.

Returned proposals

SE-0302 has been returned for revision.

SE-0302 is accepted in its basic approach. It will be revised according to the above decisions, and the community will have an opportunity to review the result shortly. We ask that reviewers focus on just the changed aspects of the proposal, unless they feel that something important was missed in the first review.

Proposals in review

SE-0295: Codable synthesis for enums with associated values is under a third review.

For the third review, the goal is not to re-litigate the entire proposal, but to focus on reviewing the additional details around the schema evolution. The updates for handling of certain overloaded enums and the choice to exclude certain enums from auto-synthesis due to evolution restrictions as specified in the proposal are also in scope.

SE-0302: Sendable and sendable closures is under a second review.

This is a narrow re-review, and reviewers should focus on the changes made in the first revision, which are described in the announcement post. To briefly summarize them:

  • The @concurrent function attribute is now named @sendable.
  • The ConcurrentValue protocol is now named Sendable.
  • The UnsafeConcurrentValue protocol no longer exists, but Sendable conformances may be explicitly decorated with @unchecked, e.g.
class MyClass: @unchecked Sendable {}
  • Non-public struct and enum types now implicitly conform to Sendable if their stored properties and case payloads all conform.

SE-0300: Continuations for interfacing async tasks with synchronous code is under a third review.

Following the second review of this proposal, the core team feels that the proposal is close to acceptance, and is an important feature as part of Swift’s concurrency roadmap. However, a small number of amendments have been made based on feedback during the second review.

  • Replaced separate *Continuation<T> and *ThrowingContinuation<T> types with a single Continuation<T, E: Error> type parameterized on the error type.
  • Added a convenience resume() equivalent to resume(returning: ()) for continuations with a Void return type.
  • Changed with*ThrowingContinuation to take an operation block that may throw, and to immediately resume the task throwing the error if an uncaught error propagates from the operation

SE-0304: Structured Concurrency is under a review.

async/await is a language mechanism for writing natural, efficient asynchronous code. Asynchronous functions (introduced with async) can give up the thread on which they are executing at any given suspension point (marked with await), which is necessary for building highly-concurrent systems.

However, the async/await proposal does not introduce concurrency per se: ignoring the suspension points within an asynchronous function, it will execute in essentially the same manner as a synchronous function. This proposal introduces support for structured concurrency in Swift, enabling concurrent execution of asynchronous code with a model that is ergonomic, predictable, and admits efficient implementation.

Swift-evolution threads: Pitch #1, Pitch #2, Pitch #3

SE-0226: Package Manager Target Based Dependency Resolution amendment is under a review.

The amendment goal is to address a usability issue introduced in the original design of target based dependencies and was discussed in a recent pitch thread on the topic.

Swift Forums

Doug Gregor updated us about changes to the actors proposal.

  • Allow cross-actor references to actor properties, so long as they are reads (not writes or inout references) Added isolated parameters, to generalize the previously-special behavior of self in an actor and make the semantics of nonisolated more clear.
  • Limit nonisolated(unsafe) to stored instance properties. The prior definition was far too broad.
  • Clarify that super is isolated if self is.
  • Prohibit references to actor-isolated declarations in key paths.
  • Clarify the behavior of partial applications.
  • Added a “future directions” section describing isolated protocol conformances.

James Sherlock pitched an idea for how the Swift language could be evolved to add a new access control keyword designed for use in Swift Packages.

Swift currently has a handful of access control modifiers, namely: open public internal private fileprivate. These keywords change the visibility of parts of our code to change what other parts of our codebase have access to said code.

Swift Packages define targets which are groups of code. Targets can depend on other targets, and multiple targets can be combined to create a product. A product can be a dependency of another application or package.

Slava Pestov started a discussion about formalizing Swift generics as a term rewriting system.

Previously I wrote about how the full generality of the Swift generic system is undecidable. The basic idea is that “finitely-presented monoids” can be written as a Swift protocol where the “word problem” on the monoid reduces to proving an equivalence between two types. Since the word problem is known to be undecidable, this shows that Swift generics (as currently defined) are undecidable.

Tim Condon pitched the MultipartKit to the SSWG. MultipartKit is a Swift library for encoding and decoding multipart form data based on SwiftNIO. It contains a C library used for the actual parsing of the request data and a Swift wrapper to integrate the C library with SwiftNIO.

Multipart is a popular mechanism for sending data to servers, especially when doing file uploads. It’s supported by both browsers and HTTP libraries and we feel that having a Swift implementation in the SSWG is an important step for the ecosystem.

MultipartKit was originally built into Vapor for the release of Vapor 4 with the intention of splitting it out at a later date and pitching it to the SSWG so here we are! Since the implementation has been used in Vapor 4 it’s fairly well battle tested and deployed.

Tom Doron posted the Swift on the Server Workgroup Jan 20th, 2020 meeting notes.

Pavel Yaskevich pitched an idea to allow interchangeable use of CGFloat and Double types.

When Swift was first released, the type of CGFloat presented a challenge. At the time, most iOS devices were still 32-bit. SDKs such as CoreGraphics provided APIs that took 32-bit floating point values on 32-bit platforms, and 64-bit values on 64-bit platforms. When these APIs were first introduced, 32-bit scalar arithmetic was faster on 32-bit platforms, but by the time of Swift’s release, this was no longer true: then, as today, 64-bit scalar arithmetic was just as fast as 32-bit even on 32-bit platforms (albeit with higher memory overhead). But the 32/64-bit split remained, mostly for source and ABI stability reasons.

Tim Vermeulen pitched an idea about efficient Collection.startIndex throughout the standard library.

Collection.startIndex is expected to be an O(1) operation, but some collections in the standard library deviate from this, which can lead to unpredictable performance. We should change these collections to properly meet this O(1) performance expectation, by doing any expensive work needed to reach the first element ahead of time, in the collection’s initializer.

Doug Gregor informed us again about more revisions to the Actors proposal.

After yet more interesting discussion in pitch #4 (and 5), we’ve revised the actor proposal for this, pitch #6, addressing more feedback.

Changes in the sixth pitch:

  • Make the instance requirements of Actor protocols actor-isolated to self , and allow actor types to conform to such protocols using actor-isolated witnesses.
  • Reflow the “Proposed Solution” section to get the bigger ideas out earlier.
  • Remove nonisolated(unsafe).

Gwendal Roué pitched a proposal about introducing scoped functions.

Scoped Functions are functions that enhance the leading dot syntax inside their body, so that it gives short-hand access to the members of a specific value. Such functions exist so that API designers and their consumers can collaborate towards a way to write focused code where an agreed implicit and obvious context does not have to be spelled out.

Nate Cook pitched an idea to codify end-of-iteration behavior for AsyncSequence and its iterators to match the existing Sequence protocol.

The recent proposal for asynchronous sequences left open a question about how asynchronous iterators must behave when reaching the end of their elements. We should amend the proposal to clarify that after returning nil or throwing an error from an iterator’s next() method, all subsequent calls to next() must return nil.

Finally

fatalError(“this should never happen”)