Papercut: The Swift Postmortem (2022)

This post was flagged by the community and is temporarily hidden.

2 Likes

1a. Deliberate design choice. Many disagree with it, but there's no objectively-correct answer.

1b. You have neglected to state the principles you think are being violated by forced unwrapping and casts, but the crashing behavior seems entirely consistent to me. One of Swift's principles is safety, by which it is meant that a program should crash rather than continue with an unknown state. Optional versions of both exist for those who are ready to handle unwrapping and casting failures at runtime.

1c. The Result enum was not added to address either concern.

2a. Many people were waiting years for some form of language-level concurrency to be included. For those people, async/await and the entire structured concurrency was a long-overdue evolution.

2b. Swift Concurrency (aka structured concurrency) is not promises.

3. Playground support is an internal Apple project that is not tied to Swift Evolution.

4. Linux support has been improving steadily. It would be nice if Apple themselves supported it better, but it's entirely understandable that their priority is their own platforms. Nothing is stopping the Linux Foundation from funding improvements.

5a. This is an unsubstantiated and purely subjective position. What you consider feature creep, others consider welcome improvements and additions (see Swift Concurrency).

5b. SwiftUI is an internal Apple project, which has brought us result builders and property wrappers. Recent work with introducing RegEx has led to improvements in result builders, and they are being used by many third parties to provide DSLs. Property wrappers have been enthusiastically adopted by a wide range of Swift developers. They have a few rough edges, but they have been useful and usable from day one.

6. A macro system built in to the language is a desired feature of many.

7. Still a work in progress. I'm no computer scientist or compiler engineer, but my take on many threads over the years is that it's not a simple feature to design or implement.

8. What does this mean?

9. Such as what? Reflection is an area of active work. What capabilities would you like? Why haven't you pitched them?

10. Now this I can agree with 100%. If protocols could be nested in enums (and other types), I would be less bothered.

11 Likes

You can use Task if you want to store a reference to a job to similar to how you might with a promise. Other than that, I don’t see why this feature should be native to Swift Concurrency. Third parties can still implement such a system, perhaps with better safety guarantees from structured concurrency.

I'm not sure what you intend to achieve by this post (and the domain name linking here). Do you have any constructive feedback, pitches, proposals, bug reports, or pull requests?

12 Likes

Seems like this is a new user, because the old user was flagged for bad conduct?

2 Likes

I share a lot of the gripes here, but the overall construction of this post seeps of technical ignorance (I don't mean that to be insulting, but there really is some naiveté here). Topped with a ranty tone, it really discredits any valid criticism that might be sprinkled in there.

For example, dismissing async/await as merely "promises needlessly being incoporated into Swift" is patently absurd, shows such a profound lack of understanding of the fundamentals. It's pretty hard to respond in any way other than a lecture about the 9001 issues of promises and how stackless coroutines are completely different with a totally different set of trade offs (which are preferable for the design space Swift targets)

Chesterton's fence applies.

11 Likes

Don't want to sidetrack this thread (if there anything to sidetrack!), but would love to see that lecture.

2 Likes

I'm not an expert personally, but I'll defer to those who are: Why stackless (async/await) for Swift?

TL;DR: Implementing async/await as sugar over Promises like in JS or Python just leads to a linked list of promises. It's a very simple and straightforward implementation with fantastic backwards compatibility, but it's a pain train of heap allocations and indirection (which is marginally cost in itself, but it prohibits a lot of other optimizations). Coroutine based async/await is much more complicated to implement (but luckily that's done already, great work team!), but better in every other way I can think of.

Not that winning a popularity contest means it's necessarily better, but it's worth noting that C#, Rust and Go have all gone with some flavour of coroutine (stackful or stackless) as their backing primitive for async/await.

8 Likes