Before heading into the holiday period, we have some great news about
async/await. The proposal adding this functionality is under review. It’s a good opportunity to express your opinion.
We have some news from the Swift Server Workgroup. Three new people have joined to help support future efforts.
We end this year with a notable and very welcome initiative - Diversity in Swift. The Diversity in Swift workgroup will use the Community Showcase to brainstorm ideas and topics for these community-focused blog posts. The first post curates helpful resources for accessibility and inclusion in Swift, all made by awesome developers from our community.
This brief is the last issue of the year. We are taking a small festive break and will be back in early January.
Evoking the spirit of philanthropy, if you’d like to sponsor the Weekly Brief when we return, please get in touch.
Wishing you the happiest of holidays and a fantastic New Year! 🍷
This week’s issue is supported by Dave Verwer who co-created the Swift Package Index, and publishes iOS Dev Weekly every Friday. He’s been a big advocate for the Weekly Brief since it started, and is supporting us because he wants to see it continue! It’s that simple.
- SR-13969 [docs] Describe how to quickly compile a minimal multi-module project
News and community
Commits and pull requests
The feedback from the pitch and first review helped ensure Package Collections are useful and put the Swift packages ecosystem on the right path. During the first review, several community members requested to learn more about the Package Collection data format and the proposal was amended to include this information. The feedback from the 2nd review was generally positive and the proposal has been accepted with one minor revision: The spelling for the command should be singular (
swift package-collection) instead of plural (
The feedback from the pitch and review was positive and the proposal has been accepted with a minor revision: The proposal should explicitly call out that starting with SwiftPM tools-version 5.4, declaring an executable target by using .target and having it inferred to be an executable by the presence of a top-level source file named main.swift is considered deprecated; That SwiftPM will continue to infer such targets as executable for a transition period but will eventually stop doing so and treat all targets declared using .target as library targets; And that in the transition period, using .target with main.swift will emit a warning or a fix-it based on technical feasibility.
Most of the discussion in the feedback thread centered around a central question of “what is the type of a function that has a property wrapper parameter?”. The proposal describes a model where the wrapper is part of the exposed type (for example
(Binding<Item>)->Void), but many data points in the thread argued for a model where the exposed type of a function is the unwrapped type (for example
Proposals in review
Modern Swift development involves a lot of asynchronous (or “async”) programming using closures and completion handlers, but these APIs are hard to use. This gets particularly problematic when many asynchronous operations are used, error handling is required, or control flow between asynchronous calls gets complicated. This proposal describes a language extension to make this a lot more natural and less error prone.
Swift Package Manager downloads dependencies using Git. Our proposal defines a standard web service interface that it can also use to download dependencies from package registries.
Swift’s concurrency feature involves asynchronous functions and actors. While Objective-C does not have corresponding language features, asynchronous APIs are common in Objective-C, expressed manually through the use of completion handlers. This proposal provides bridging between Swift’s concurrency features (for example,
asyncfunctions) and the convention-based expression of asynchronous functions in Objective-C. It is intended to allow the wealth of existing asynchronous Objective-C APIs to be immediately usable with Swift’s concurrency model.
Keith Smiley started discussion about supporting strict imports.
We have a large multi-module Swift codebase where we want to support strict imports, meaning files only import what they use, and they import everything they use (not particularly at the class level with import class Foo.bar, but at least import Foo). We have a few specific reasons for wanting this to be enforced:
- When reading a diff it makes it clear when a new dependency on a module is being introduced
- When this is explicitly defined we can enforce what types of modules are allowed to import what other types of modules, for example we don’t want modules with business logic importing our UI layer etc
- By trimming unused imports, we can eliminate unnecessary intermodule dependencies, simplifying the dependency graph and speeding up compilation
This is not dependent on the specifics of any of the proposals under discussion, but I wanted to explore a little bit what the introduction of async/await might mean for the way we program in the long term. I have just two related concerns at this point. I hope the proposers have considered these questions and have some answers, but I’d be interested in anyone’s thoughts.
The first pitch thread provided a bit of feedback, which I’ve incorporated into this second pitch. The specific changes:
- Removed mention of asynchronous handlers, which will be in a separate proposal.
- Introduced the
swift_async_errorClang attribute to separate out “throwing” behavior from the
- Added support for “Swift private” to the
- Tuned the naming heuristics based on feedback to add (for example)
completionBlock, and variants.
- For the rare case where we match a parameter suffix, append the text prior to the suffix to the base name.
- Replaced the
-generateCGImagesAsynchronouslyForTimes:completionHandler:example with one from PassKit.
- Added a “Future Directions” section about
Dave Abrahams raised a concern that the rule requiring a
try label on every potentially-throwing statement was too indiscriminate.
It’s not that requiring a
trylabel is always a mistake, I argued—in fact, in some cases being forced to acknowledge a possible throw could be extremely helpful in reasoning about code—it’s just that there are so many cases where it wasn’t helpful.
George Barnett asked a couple of questions about source location in literals and result builders.
One issue I’ve come across recently is the fact that you cannot access the source location of the literal triggering a call to
init(fooLiteral value: Foo, file: StaticString = #file)would fail to fulfill the protocol requirement. There was a pitch quite some time ago to allow functions with default arguments to satisfy protocol requirements, but not much seems to have happened as a result. Result builders might have a similar problem, as it seems one cannot write
static func buildExpression(..., file: StaticString = #file), though since this particular method participates on overload resolution it may just work.
Swift on the Server Workgroup meeting notes:
- October 28, 2020 by Kaitlin Mahar
- November 11, 2020 by Peter Adams
- December 15th, 2020 Special Update by Tom Doron
Michel Fortin started a discussion about interlocking in a hierarchy of actors.
I think it’s a bit of a problem that actors can’t talk to each other synchronously. I’m trying to find a model that would allow synchronous calls from actor to another actor while avoiding deadlocks and limiting blocking. So this an the idea I’ve come with. I’ll be keeping an updated version of this document here.
Task local values provide a much needed missing piece in the Task infrastructure puzzle. It enables instrumentation, profiling and tracing tool authors to build truly great contextualized experiences for debugging, profiling and tracing codebases using asynchronous functions and actors.
At the same time this proposal avoids pitfalls of similar APIs thanks to embracing Swift’s Structured Concurrency approach.
Please refer to the complete and up-to-date pitch document