Swift Stories |
View in web browser |
Featured work: Matthew Skiles
#1 - Jan 10, 2025 Welcome to Swift StoriesWelcome to issue 1!
We are excited to kick off 2025 with a new project: Swift Stories, a newsletter designed to be a welcoming space for fresh voices to share their stories and ideas.
Swift's structured concurrency introduced a powerful new mental model, enhancing app stability by catching data race issues at compile time. If you haven't adopted it yet, consider exploring it with this resource as a reference. One intriguing aspect of structured concurrency is how its underlying concepts mirror ideas from Erlang's VM. In Swift, we have isolation domains, and in Erlang, we have processes. Both languages allow passing types safely across boundaries: Swift uses Sendable types, while Erlang relies on copying any type across processes. This shared principle of isolation underpins their ability to manage concurrent tasks effectively. Unlike Erlang—which was designed with concurrency as a core principle—Apple had to integrate structured concurrency into an existing ecosystem of legacy code and patterns. This required reconciling the new mental model with an “unsafe” past while making the compiler aware of these scenarios. Despite this incremental approach, it’s fascinating to imagine how the app ecosystem could evolve if programming languages and their standard libraries fully embraced domains and message passing as the foundation for architecting code.* Joe Armstrong, one of Erlang’s creators, introduced the concept of "Concurrency Oriented Programming Languages" (COPLs). He said:
Imagine, for a moment, if we modeled the business logic of our apps after concurrent actions instead of artificial constructs like interactors, controllers, and services—structures that don’t exist in the real world. This approach in Erlang enabled solutions that are simple by design. A similar shift in Swift could open doors to fault-tolerant, maintainable, and scalable apps, particularly as Swift expands into server environments. Instead of prioritizing classes, structs, enums, and design patterns like repositories, builders, or adapters, we could focus on the core unit of isolation domains: actors. Actors could even supervise child actors, as in Erlang. For instance, an actor managing local data could have child actors responsible for individual data types. If a child actor crashes, the system could automatically restart it, introducing resilience. This actor-based mental model not only enhances data race safety but also enables fault tolerance by turning isolation domains into error boundaries. Isolation domains can also revolutionize testing. If each end-to-end interaction with the app were modeled as an actor, you could test numerous interactions in parallel with minimal risk of flakiness in your test suite. This safe parallelism scales testing while maintaining reliability. We believe these new mental models can radically improve app stability, maintainability, and testing scalability through safe parallelism. Adopting these ideas requires deeper familiarity and a willingness to think outside the box, but the building blocks for this transformation are already in place. Tools & sites
Worthy Five: Jeff DickeyJeff Dickey, known on the Internet as @jdx, is a software engineer with a passion for open-source and developer tools. You might know him from his work on the Heroku CLI, the OCLIF Framework for building CLIs, and most recently Mise, a front-end for dev environments.
Food for thought
|