Changelog Interviews – Episode #566
All the places Swift will go
with Ben Cohen, Swift Team Manager @ Apple
This week we’re talking about Swift with Ben Cohen, the Swift Team Manager at Apple. We caught up with Ben while at KubeCon last week. Ben takes us into the world of Swift, from Apple Native apps on iOS and macOS, to the Swift Server Workgroup for developing and deploying server side applications, to the Swift extension for VS Code, Swift as a safe C/C++ successor language, Swift on Linux and Windows, and of course what The Browser Company’s Arc browser is doing to bring Arc to Windows.
Featuring
Sponsors
Statsig – Build faster with confidence. Startups to Fortune 500s rely on Statsig to make data-driven decisions. Ship smarter and faster with the unified platform for feature flags, experimentation, and analytics. Our listeners get free white-glove onboarding, migration support, and 5 million free events per month.
Neon – The fully managed serverless Postgres with a generous free tier. We separate storage and compute to offer autoscaling, branching, and bottomless storage.
Fly.io – The home of Changelog.com — Deploy your apps and databases close to your users. In minutes you can run your Ruby, Go, Node, Deno, Python, or Elixir app (and databases!) all over the world. No ops required. Learn more at fly.io/changelog and check out the speedrun in their docs.
Typesense – Lightning fast, globally distributed Search-as-a-Service that runs in memory. You literally can’t get any faster!
Notes & Links
- Swift is available for macOS, Windows, and Linux
- The Browser Company (who are bringing their Arc browser, written in Swift, to Windows) recently open sourced their bindings for WinRT
- The Swift on Server Working Group
- Swift extension for VS Code (if Xcode isn’t your thing)
- NSA recently published a report urging people to move off of C and C++:
- John McCall (who chairs the Language Steering Group) at CppNow recently
- The goals for Swift 6
- Miguel de Icaza proposing using Swift in the Godot game engine
Chapters
Chapter Number | Chapter Start Time | Chapter Title | Chapter Duration |
1 | 00:00 | This week on The Changelog | 01:11 |
2 | 01:11 | Sponsor: Statsig | 03:25 |
3 | 04:36 | Start the show! | 03:11 |
4 | 07:48 | Realizing the vision | 01:58 |
5 | 09:46 | Swift as a language | 04:53 |
6 | 14:39 | Swift on Windows and Linux | 05:33 |
7 | 20:12 | Migrating to Swift | 02:17 |
8 | 22:29 | Swift on Windows | 03:57 |
9 | 26:27 | Sponsor: Neon | 05:21 |
10 | 31:48 | Swift on Android and elsewhere? | 03:18 |
11 | 35:06 | Swift vs Rust | 02:23 |
12 | 37:29 | ABI stability | 05:30 |
13 | 42:59 | Swift and memory management | 02:17 |
14 | 45:16 | Swift ergonomics | 04:41 |
15 | 49:58 | Swift and The Godot Engine? | 02:00 |
16 | 51:58 | Coming up! | 01:44 |
Transcript
Play the audio to listen along while you enjoy the transcript. 🎧
We’re here with Ben Cohen, from the Swift team at Apple. Welcome.
Thanks a lot. Happy to be here.
I’m curious why you personally, a Swift team manager, why are you at KubeCon, specifically?
Yeah, so Apple has loads of people here. We’re giving several talks… So mostly from the cloud side of things, obviously; we’re big users of a lot of software that’s on show here, and it’s great to be a part of this community. Me myself, I used to be a server developer for many years, but I’ve been out of it for, I guess, the eight years that I’ve been working on programming languages. So I’m kind of – this is my way of immersing myself back into what the latest is in tech… Because when I was last doing this kind of thing, we were really banging rocks together and running stuff for via cron and it’s –
cron rocks? – cron is banging rocks?
Well, you know… There’s a lot of impressive stuff here, right?
Okay, okay…
We’re cavemen, Adam. We bang the rocks together…
Point taken… I’m still using Bash, too. Is that an issue?
Zsh is cool too, but…
I use Zsh as well. But I write Bash in scripts, executed with Zsh.
Okay, you’re using all the rocks.
That’s right. All the rocks.
So we just spoke with somebody – who was it? Jared Henderson we were just having on the show. He’s building a Mac app, and it had REST API, and the management, and stuff, and he’s like “I’m doing client-side Swift, I’m doing server-side Swift…”
Oh, that’s cool.
…and I was like “That’s pretty cool.” I don’t think most people know that server side Swift is a thing. When I think of Swift, I think of like “You’re going to build an iOS app”, or Mac app, of course. But that’s just kind of the pigeonhole, unfortunately, that in my mind it’s in. But it’s apparently a lot more than that now. Do you wanna talk about some of that?
Yeah. So it’s great to have an opportunity to talk about this stuff. So server side Swift has been a thing for some time. I think, presumably, Jared is using some of the great frameworks that are out there. So there’s a technology called Vapor, which is kind of a Rails-like –
That’s what he’s using, and he mentioned another one called Hummingbird.
Yeah, Hummingbird is more of like a cut-down, kind of when all you want – when you don’t need a whole framework to bring up a site, you just want to respond to HTTP requests. So that’s more of a lightweight thing. And they’re both pretty cool. The authors of those technologies sit on our Swift on Server working group that we have, that’s kind of following a similar pattern to CNCF, where they have libraries and frameworks, and they try and incubate them, and then graduate them to officially endorse things. And yeah, it’s an opportunity for people to write the same code that they write on their devices, on the server side. Obviously, there’s a big win there, which is you get to share code between the two places… But even if that’s not something that you’re into, we think Swift is a great opportunity for high-performance, but approachable language on the server side.
[07:48] Yeah. Obviously, he didn’t start there. I do remember when Swift was first launched, free open source, and Chris Lattner talked about some of the design decisions that he made… Very ambitious. It was like scaling down to like a single script, all the way up to like huge applications and stuff. Has that vision been realized, in your opinion?
I think so. I mean, we’re seeing recently some pretty exciting developments. So just in the last couple of weeks we introduced a vision document, with the language steering group that I’m a member of, that sets the direction for the language. There’s a sort of open process that we have on the forums that we run at Swift.org; we have these things called Vision Documents, that are kind of our vision of roadmaps that set out larger language features. So when we introduced concurrency a couple of releases ago, that started off with a vision document, and then individual pieces of the language get proposed as a part of that.
One of the latest vision documents that we just officially approved was for something called embedded Swift, which is the ability to slightly subset down the language, to a point where you can build statically-linked binaries that are really tiny. So if you look at the vision document, it actually has a video of us running on one of these STM32 boards, which have just one meg of memory. A really tiny binary that bounces a Swift logo around an LCD screen… And up until recently, that involved statically-linking the entire Swift runtime into the binary; that would end up being about 600k, which would fit on a lot of things, but not something that small. That binary now strips away all of the dead code, and gets you down to the point where the binary for this little demo is just 15k, and 10k of that is actually the image of the Swift logo. So it’s really just 5k of code. And that allows us to target new environments, but using the same language, with all of the same sort of high-level feeling features that you get with a regular piece of Swift code, subsetting out just a few things that need heavy runtime support, like reflection and things like that.
That’s cool. So for those who haven’t written any Swift - probably lots of people with Java backgrounds, JavaScript backgrounds, Go, Rust, whatever it is - how do you characterize the language in terms of typing, in terms of paradigm, is it OO, is it functional? If you were just gonna give like the elevator pitch of “Swift, the programming language features”, how does it fit into other programming languages?
Yeah, so the way I like to introduce Swift is actually - I go back to when I first saw Swift, and what really got me into Swift. So I actually wasn’t a member of the team when Swift first launched. I joined about a year or so later. And at the time I was actually working in FinTech, I was working for a bank, working on trading systems.. So we were a team, doing sort of equity and derivatives trading, we had full stack development, server-side and UIs… And we were using various different languages. So we were using, on the server side for these trading systems, that really needed high performance and low latency, we – the developers separated into two camps. You had the Java programmers, and the C++ programmers. And the Java programmers, they were really fighting the garbage collector all the time. Because every millisecond counted, they were making sure not to allocate too many objects, and using ring buffers of scalar types, and things like that… And they would look at the byte code to make sure everything was going well. And the C++ programmers found this hilarious. They were like “Why don’t you use a proper language?” But it wasn’t so funny when C++ code would segfault in the middle of the trading day, right?
So that was the server side. You had two camps of developers who had chosen a language, and that forced them into a pretty tough choice - safety versus performance. Then we had UI programmers; they targeting Windows, they were using Visual Basic, and then C#. C# - kind of a nicer language, I would say (this my personal opinion) than Java. It came out slightly after Java, and I felt like it was slightly improved, similar style. Obviously, they were enthusiastic about that, but they were, again, sitting on top of a garbage-collected language. And then we also had less latency-sensitive things; we would have Ruby programmers writing Ruby on Rails apps for things like static data maintenance.
[11:53] Ruby is such – I remember I actually listened to one of your podcasts where you had Justin Searls on, and he was talking about how Ruby, how they really focus on the joy of programming, and how it was such an enjoyable language to program in. But obviously, it doesn’t scale to the kind of latency-sensitive environments that you need for that sort of thing.
So it was really interesting that we were all using all of these different programming languages. And obviously, I think people should learn different programming languages; it sort of expands your brain, and makes you a better programmer. But it was kind of unfortunate, the choice of language really limited them in some way. And so my first impression when I saw Swift, when Chris announced it on stage, was like “Yes, this is what we need.” Because it was a non-GC language, compiles down to native, but it had that higher-level feel that actually made it really enjoyable to program in, a lot like Ruby.
So I think the sort of ambitious elevator pitch for Swift is that it’s something that you can achieve C++ level performance in. Obviously, you have to work at it; nothing comes for free when you’re actually operating that level. But the language itself feels a lot higher level, a little bit more like Ruby. Obviously, it has a static type system, but we worked hard with things like type inference, to make sure that the types aren’t in your face… We try and put an emphasis on progressive disclosure, so that – obviously, one of the key things for us is we want app development, which is the main demographic for Swift, to be easy to do. We want somebody to be able to sit down, not have the language get in their way, but also, we want the language to be powerful enough that the framework developers can create things like SwiftUI, that is like this super-high level programming language that allows people to be very productive, put together apps super-quickly. And so I guess that’s how I’d characterize it. It’s a native language, but with a high level look and feel.
Okay. It sounds somewhat too good to be true, but… [laughs]
Obviously, this puts a lot of stress and strain on the compiler itself. So that’s why we work pretty hard, to work on the performance, through the optimizer, obviously… We’re a reference counted language, so we don’t have GC pauses, but sometimes we have more reference counts than you want, and that’s where the optimizer has to kick in and like eliminate things, and prove that there are optimizations there that can make it more efficient. But for the most part, we think we’re achieving that goal, and we just want more people to enjoy the language like we do.
Yeah, I think breaking it out of the Apple bubble has always been interesting to me, and open sourcing it was like step one of that. And if you look at C#, for instance, it’s very much – it is where it is. I mean, maybe they’ve made inroads, and it’s obviously Microsoft themselves who started to open source tons of stuff… But I was surprised to find in your email that it’s available for Windows and Linux. I mean, I didn’t even know that. I think I knew Linux maybe, but had forgotten… Is this like native Windows support for Swift, or how is it–
Yeah, yeah. So Linux we’ve had since the first day of open source.
Yeah, I remember that.
And more recently, we adopted Windows as an officially-supported platform. So that was actually a community effort. So it was driven by a member of the core team who actually now works for the Browser Company, who are themselves using Swift to bring their Mac and iOS browser to Windows. And they actually recently published an article where they’re using Swift to wrap the Windows APIs. They’ve actually got a really interesting implementation of COM, which is the way that Windows interoperates with its API, that integrates really natively with Swift.
I think one of the links I sent you, that maybe people can find online, is about how they believe - and we agree - that interoperability is one of Swift’s superpowers. So one of the things that Swift can do is interoperate directly with C-based languages. So this was actually how we bootstrapped the original ecosystem for Apple devices. So on day one, you launch a language - it was there at WWDC; you could download it that day. But when you launch a language from scratch, it doesn’t have an ecosystem, except Swift did from day one, because we have this ability to interoperate directly with C, and in Apple’s SDK’s case Objective-C. So when you import an Objective-C header file into Swift, it comes in and looks and feels like a Swift library. You can create the objects, you can call methods on them as if they were Swift-native methods.
[16:20] One of the things that’s nice about the Objective-C ecosystem is that they had these really well-adopted naming conventions for their methods and their types. And that was really nice, because we were able to – Swift has also some great guidelines around how to name methods, but they weren’t the same as Objective-C. But because the Objective-C ecosystem was so consistent, we were able to do some tricks where we basically renamed the methods, so that they actually come into Swift looking what people will refer to as Swifty. They feel natural. So that was actually the way that we bootstrapped the original ecosystem.
Now, sitting on top of Objective-C meant we also had to have C interop as well. And that’s actually a really interesting opportunity on the server side, because obviously, we have folks who have written code that they felt had to be written in C. Like I was talking about right at the beginning, people who actually really, really need that low latency, high performance, they would usually pick C or C++. And I think in this day and age, unfortunately, that’s something that’s a real problem, because of the lack of safety in those languages. And the NSA, I think, about a year ago, put out a white paper urging people to start moving off of unsafe languages. And Swift was one of the safe languages that they suggested, as well as C#, Java, Rust… But we feel that Swift has two advantages in this area. One is if you’re going from C or C++, maybe you can afford to go to a managed language like Java, but maybe you can’t. And so Swift, alongside Rust, has the ability to compile natively. But Swift has the advantage, one, that we think that the high-level feel of the language pays dividends in terms of productivity when you make the shift from C++ to Swift.
We actually have been slowly rewriting the compiler ourselves in Swift; when it first came out, it was all written in C++, obviously, because you can’t self-host if you haven’t got a language yet… But we’ve been doing that migration and I was doing some work on our parser recently, and we have to do it twice at the moment, because we have the old parser and the new parser, before we swap the new one in… And it’s so much nicer to be writing in a higher-level language, that feels a lot more productive. So there’s that advantage.
The other advantage is that Swift, actually as of last release, now has C++ interoperability, as well as C. And so similar to Objective-C, C++ types come in and look like native Swift types. You can call methods on them with Dart, and things like that… And we don’t have – you often hear this term FFI, Foreign Function Interface, that a lot of other languages use to interoperate with C. So if you use Go or something like that, you have to create bindings, and then go through this FFI layer. Swift doesn’t have that. We basically use the C compiler, Clang, that’s also part of the LLVM project. It essentially is a library to bring in C API directly. And that means that we skip the FFI layer. That has an efficiency benefit, but it also means that we can really integrate those things nicely, and you don’t have to generate bindings.
Now, why is that important? The key thing there is that means that just like with apps transitioning from Objective-C to Swift, if you’ve got a big C++ server installation or library, you can do the migration essentially function by function, file by file. So it’s not a big bang rewrite… Which is normally where these kinds of initiatives go to die, right? You’re like “Oh, God, okay, we’ve got this existing installation that’s all written in C++…” What are your choices? You can either break it up into microservices, which has consequences in terms of performance, and all sorts of things like that… You’re gonna have to monitor multiple things… Or you can try and like smoosh your new language in this existing service together, and that ends up being pretty painful. With Swift, we think that it’s a much easier migration, because you can just directly interoperate with your C++ code as if it was native Swift code.
[20:12] How frequently is that migration happening? You said the NSA suggesting Java and Swift and others as safe languages to move to… It’s got to be an initiative of you all’s, like you mentioned, the vision aspect of it, to enable paths to migrate. How much out there is to be migrated? Is it just a ton?
Oh, yeah –
Obviously, right? There’s a lot of code out there to be migrated to – and you wanna be the target of that migration.
Right. Exactly. So we think that if people are heeding that warning and saying “Oh, maybe I should think about getting off of my existing C codebase”, that we’re a great opportunity for people to adopt us. And both level up in terms of a language that’s easier to use, but also make it a less painful transition, where it’s not just a rewrite. Because one of these problems with rewrites like that is you end up with the rewrite team and the legacy team, and there’s this really sometimes unhealthy dynamic there, where “Which team are you on?” and sometimes the legacy team are like “We want to stick with this thing” or “We want to enhance the existing old thing.” And the rewrite team are always like “Oh, we’ve got to rewrite everything before we can move on to the new thing.” If instead you’re at the code level introducing a new language bit by bit, you can mix it up a little bit. You don’t need to have two separate teams for the new thing and the old thing. You can just say “Okay, today I’m adding this new feature. I’m going to write it in Swift.”
There’s a couple of great talks on this that we gave recently. One was actually at Strange Loop, where Konrad from the Swift team talked about how we introduced Swift into an existing open source Apple Project, FoundationDB, which is actually sort of a database technology that we use on the iCloud side… And introduced Swift into that. And that could be done incrementally. And then there’s another talk that John McCall, who actually chairs our language steering group, gave at CPPNow, which is this C++ conference… Where interestingly there were multiple people giving talks about successor languages. It’s kind of funny to go to a C++ conference and say “Hey, you really want to think about getting off of C++.” And he has a lot of credibility in that area. He worked on Clang for years. So he’s an expert in the language, he is the maintainer of some of the standards documents… But he’s basically there to say “Hey, we’ve got to start thinking about this, we’ve gotta start moving on.” And we think that this is a realistic path that you could take.
When did the support for Windows come about, and is that also part of this welcoming banner? Like, it’s a migration target in terms of C++ to Swift, but also to be able to develop on Windows. Is it a runtime that’s on Windows? Is it a development environment that goes somewhere else? Like, describe the Windows support, and the initiative behind that.
Yeah, so like I say, Saleem and the folks at the Browser Company have done some really heroic efforts in wrapping some of the Windows SDKs. And I’m not going to speak for them, because it’s their work, but I suspect the answer is mostly that they’re not looking to create a cross-platform SDK. They want a language, in this case Swift, that will compile Windows binaries, and have that able to access the existing SDK, just like Swift accesses the existing SDK on Apple platforms.
So there is a bit of a runtime in terms of obviously we have a standard library that you can use, we also have taken the next level above the standard library, which is something called Foundation… That’s something that Apple developers will be very familiar with. It’s been around for a long time as the core part of Apple’s SDK.
When Swift first launched - obviously, Foundation itself, when Swift first launched, was written in Objective-C. And the initiative at the time was we were going to create this parallel version of Foundation written in Swift. Unfortunately, the challenge there is those two things got a little bit out of sync, because the Objective-C implementation on Apple’s side wasn’t identical in every way to the implementation on what we refer to as Corelibs Foundation on the Linux side. And people found that a little bit challenging. I think that was one of the reasons why Swift on Linux adoption stalled a little bit in the early days.
[24:13] So about a year ago, at the Swift on Server conference, Tony Parker from the Foundation team announced something new, which is that we were open sourcing a new, pure Swift implementation of Foundation, that was actually going to be the implementation at Foundation, that if you are running iOS 17 is on your phone. And so that’s actually identical code now that we’re open sourcing, and that you can run on Linux and Windows as a package that you download and compile into your binary… Whereas on iOS, it’s there in the frameworks that you use.
And it was a while to get to this point, because we had to do quite an interesting trick, which is we actually had to invert things. We originally had a library written in Objective-C, and then we were sitting on top of it as Swift. And we had to flip that around, so that actually the implementation of Foundation was written in Swift, and then we had to reexpose all of that functionality back to existing Objective-C apps.
One of the things we have on Apple platforms is we have this ABI stable platform where you can write an app, put it up on the App Store, and then the operating system upgrades underneath it without you having to redownload the apps. And that’s really important, and that relies on the technology of ABI Stability, which is something that Swift implemented, I guess three years ago now, with Swift 5.0… Which was a really important point for us, because that allowed us to start implementing parts of our operating system in Swift. Up until that point it was only a technology that we could use internally within the operating system, but we couldn’t expose frameworks written in Swift. But once we achieve that, we were able to do that inversion of Foundation, and now we’re at the point where we’re starting to open source code that is literally the identical code that you’ll be running on your phone, built into the operating system on Windows or Linux as well.
So Swift on Mac, Swift on Linux, now Swift on Windows. Obviously, Swift on iOS. Swift on Android…?
So there is a community effort… So like I was saying earlier, Windows became an official platform relatively recently. And what happened up till that point is it was really this community effort where community members took the open source Swift and made it run on Windows.
The hackers are gonna hack. [laughs]
Exactly. So hackers hack, and then they get it going… They do a really amazing job. And then they have to deal with all sorts of struggles. In the case of Swift on Windows now all of a sudden we have to compile the compiler with Visual Studio, which is always fun, because C++ compilers don’t always agree… So they did that work, and then at that point, once it graduated, it became an official version of the language.
We have people who are working on Android, and they’re still in sort of the community bringing it up stage. We also have a community effort to implement WebAssembly as well.
Oh, nice.
And hopefully at some point we’ll stabilize and graduate it.
Yeah, that’s cool. And the reason I think of that is we go back to Arc’s story, the Browser Company… And it’s a really cool go to market strategy. I mean, we know that a lot of new businesses, software businesses start on Mac if you have a certain demographic you’re targeting. Obviously they are with Arc, the Browser Company. But now they can use the same language and they can say “Okay, we’ve established some sort of foothold here, people like it. Let’s go ahead and develop a Windows app”, and so they’re doing that. It’d be very cool if you can start on iOS, and then as your business becomes established and you think you have something here, now move it to Android without starting brand new, right? Or going to React Native from the beginning. I mean, there’s ways that you can try to go cross-platform, but if you could have Swift to start with, and you could have all the benefits that Swift has, including the ergonomics that are nice, so you can move quickly and build something fast, and then not have to rewrite or hire a whole new team on the Android side… Obviously, there’s a difference between language runtime and the SDKs to do all the things, and the widgets and stuff, but somebody could build on top of it from there.
Right.
And I think React Native has seen a lot of people using it because it provides that kind of flow to a company. And I think with Arc moving to Windows, that’s really cool… But if you could just start on iOS, and then graduate over to Android, I think that’d be a really cool story, too.
Yeah, I think there’s a great opportunity there for the community to bring something about that works. Due to the open source nature of it, there’s nothing stopping people bringing it to new platforms. I think another thing that people have done is before we announced this recent vision around embedded Swift, people were already actually bringing Swift to embedded platforms. I think there are a couple of products that are kind of maker kit products that actually are based around Swift, and I think somebody has already brought Swift to Arduino platforms… So yeah, part of the open source nature is that anybody who has a will to make it happen for a new platform and has a great business idea can get involved.
When it comes to the moving from C and C++ initiative, there’s this big push, not just from the NSA, but there’s grassroots efforts, there’s more formalized efforts… I know - was it Josh Aas from Letsencrypt really pushing “Let’s rewrite all of the internet’s core infrastructure, open source mostly, in memory-safe languages etc.” Most of that that I’ve seen from my purview is getting rewritten in Rust. On the kind of stuff that we cover on Changelog News, it’s like “This, but rewritten in Rust”, weekly.
Yeah.
[35:40] And so Rust really has momentum there, and I wonder if you think that Swift can go toe to toe with Rust in terms of just capabilities. I know you think there’s some ergonomic advantages, which probably is the case, but in terms of momentum, it just seems like Rust has some, and I wonder if you follow that, or if you’ve insights on why that is, and how Swift might help out in that regard… Because there’s so much to rewrite.
Yeah, there is. And - I mean, anything is progress, so certainly, I think, new rewrites moving off of C into Rust are exciting to see. Like I say, I think there’s a couple of interesting things there. So Swift and Rust share a lot of similarities. Obviously, they’re both GC-free, they are influenced by a lot of the same predecessor languages… The key difference probably comes down to their approach to defaults. In Rust the default is the objects aren’t copyable by default, and need to be uniquely owned by default… Whereas Swift takes the approach where objects are copyable by default, and don’t need unique ownership. But when you need to, for either performance reasons, or for actual business logic reasons, you can opt out of copy-ability. So if you want to create a - I don’t know, a wrapper for a file handle, where it’d be bad to make a copy of the file handle and pass it off to somebody, you can opt that type out of copy-ability, and then it becomes what we call a non-copyable type. And that was introduced in the last version of Swift.
We actually have some new language proposals this year to extend that capability, make it a bit more flexible… But yeah, that’s really the key difference. The other key difference, which is kind of really in the weeds, is that idea of ABI stability. Swift has this capability of creating libraries that expose generic APIs, and are separately compiled, but are able to be ABI stable. And that’s actually a really key differentiator.
Maybe unpack ABI stability, just in case we’re assuming that everybody knows what that mean.
Totally, yeah. So as I was saying earlier, the key with Apple’s platforms is you can compile your app, and then you upgrade the operating system underneath you. And the APIs, so long as they still provide the same ABI, the Application Binary Interface, your app compiled against the old APIs can run against the new APIs. And that’s how come you can upgrade your phone to the latest version of iOS and you don’t need to redownload the apps from the App Store.
Now, that’s always been possible with C. C has really always had – I could see a world where actually C usage, maybe in a dream world, is reduced down, but C lives on as the way that different languages talk to each other, right? So if you want to talk from your Go program to your Rust program, you use C. You use the C API, and you use Cgo on the Go side, and use FFI on the Rust side.
So C has always had this ABI stability capability. But on Apple platforms we needed more than that. We needed the ability to create something like Swift UI, that exposes a rich API that’s easy to use, and is really expressive, and uses sort of much more powerful features, like generics, in a way that other languages aren’t able to provide. And the fact that we make these available whilst preserving ABI stability is something that is really key to Swift success on that platform.
Now, on Linux most people don’t really need that kind of thing. They just compile their single, statically-linked binary, and then they ship it off to the server, and so Rust itself actually doesn’t have a stable ABI. And that’s a choice they made. Their generics model actually does something called monomorphization, which is what C++ does, and that essentially means you have to compile the generic code you’re calling into your binary. Swift doesn’t have that restriction, and that therefore gives us a slight benefit. But like I said, that’s kind of in the weeds. What we what we actually think is the key differentiator is the readability benefit you get from Swift. And I think that’s actually really important, because again, if we move into a dream world where we’ve managed to move on from memory unsafe languages like C and C++, hopefully we see the number of exploits that are coming from things like buffer overruns, and use-after-free and all of these ugly things that can happen with those unsafe languages, we see those exploits reduce down… But there are still going to be exploits, and probably the next frontier after that is going to be correctness bugs.
I don’t know if you saw recently there were two CVEs issued for Curl that came out and got a fair amount of press, and one of them was a high severity issue that was a buffer overrun, I think. So a standard, like, it was written in an memory unsafe language, you can overrun the buffer; high severity, because - pretty nasty. You could, in theory, get an exploit that runs arbitrary code. So that’s bad, and we know the solution to that is that we need to move on from a memory safety point of view.
[40:24] The second CVE that was issued at the same time was actually a logic correctness bug. It was to do with cookies, and it was low severity, because a lot of things had to line up in a perfect way, and you had to have access to the file system in order to exploit it. But it allowed, I think, potential injection of a cookie as an exploit. And that was purely a logic bug. And I have this feeling that over time, as we manage to get a grip on language safety, and the number of exploits that result from things like buffer overruns go down, the number of exploits that result from correctness actually goes up. And at the end of the day, that’s going to mean that people are going to need to be able to write in a language where they can look at their code and know what it does. And there is a risk there that if we spend all of our time focusing on the memory-safety aspects, and actually that leads to a lot of ceremony in our code, that makes it less readable as a result, that actually, I suspect, means that we’re going to end up in a situation where people have a harder time writing code that’s actually logically correct, because the ceremony gets in the way. And that’s another reason why we think that Swift is a nice option there, because we try and go for a low-ceremony language… Including little niceties like Swift doesn’t have semicolons to end each line. I know it seems trivial, but every time I move back to writing a bit of C or C++ and I realize I have to put those back in, it’s a little frustrating.
Right. Yeah, that’s fair. And as a guy who’s written lots of memory-safe code, I can assure you there’s plenty of logic bugs coming out of my fingers as well… So that’s definitely gonna be a problem.
Performance as well, I think. The reality is yes, we want natively-compiled languages. I was railing on the GC pauses earlier, but at the end of the day I look at a lot of performance bugs as part of my job, and a lot of the time they actually come down to not the low-level stuff; it’s the high-level stuff, like are you actually in a for loop that inside the for loop has another linear scan on something, and so therefore suddenly when somebody has some massive input dataset, it’s a lot slower, exponentially slow, or quadratically slow, compared to a normal input dataset. And that’s actually where a lot of the performance challenges come from. It’s really similarly like the logic of the code, and the key there is to be able to have a language that feels lightweight enough that you can look at it, understand what it’s doing, and then spend your time thinking about “Oh, have I architected this right? Am I making 10 calls when I could make one? Could I do things a little more simply or more efficiently?”, that kind of thing.
How much in practice do you have to deal with memory-related things in Swift? So I’ve written some Objective-C and I know there’s automatic reference counting and stuff, but there’s also times where you have to turn that off or on, or maybe you have to futz with it… And I wrote some before that was a feature, and I retained release, and stuff… So that’s the trade-off of not – garbage collection is like, well, you’re dealing with some stuff. In Swift is all that gone? Do you still have to poke under the covers once in a while and say “You know what, there’s some memory issues or not”, or how does that play out?
So the only time when it comes up is when interoperating with another legacy language.
Okay.
So if you’re writing pure Swift, if you have that luxury, if you’re just like sitting down with a clean piece of paper and you’re just writing some standalone item, like maybe a framework or something like that, you don’t encounter any of that low-level operation. The one thing you do have to be aware of in a reference-counted language is that you can get cycles, right? So if you explicitly need to have, let’s say - the classic example is doubly linked list. If you have a link from node A to node B, and then a link back from node B to node A, that creates a cycle, and you need to break that cycle, so one of those references needs to be weak. But that’s pretty rare in practice.
[44:10] If you’re writing data structures, which is usually something you grab a package to do, then you need to be aware of that sort of thing. The only other time that comes up usually is kind of callbacks, which used to be a lot more popular up until our recent releases of Swift, because we now have async/await. So instead of having a callback where you pass in a closure and get called back, you can now await an asynchronous method call, which is a little nicer.
So really, the complexity comes when you’re interoperating with another language. So yes, there are some Objective-C libraries that don’t even use automatic reference counting, and so you have to manually retain the release. And those operations are exposed to you in Swift if you need to call them to interoperate with something.
Similarly, if you’re calling into a C library, it depends on the C library, but some C APIs expose some disgusting void *
thing, and you have to operate with it, and Swift has a bunch of affordances to allow you to try and turn those into a more strongly-typed pointer that’s a little safer; even if it’s still an unsafe pointer, it’s a little safer to operate with. So really, that’s where it kicks in, is that interoperability with those legacy languages.
So this sounds apropos of nothing, but maybe we can squeeze it into the ergonomics conversation, but I think I saw recently - did you all remove the increment and decrement operator? This was like – somebody on Twitter was just like…
I saw that this morning… I do not know why somebody dredged that up. That was a change in Swift 3.0, which I guess was six years ago…
[laughs] People are talking about it, I don’t know.
It’s all over Twitter, yeah. So yes, at the time, I think actually that change was proposed by Chris Latner at the time… Or maybe he was the review manager, I can’t remember. Yeah, we removed the pre and post increment operator, I think because the idea is they’re a bit of an attractive nuisance. I think if it was just a pre increment or a post increment operator, that might make sense. But having two - that should not be the thing that people encounter as they’re first learning a language, is like “Oh, what’s the difference between pre and post?” There’s all sorts of myths on the internet about how one is more efficient than the other, and things like that.
So yeah, in the early days of Swift there was a lot of rapid motion with the language. That was actually one of the things that was a bit of a challenge for the very early adopters from the Swift 1.0 days, is the language did go through a fair amount of churn. Since I think Swift 4 we actually adopted a policy where there are no more breaking language changes, except with a major version upgrade. And so basically, when we introduce a new major language version - and the next one is actually going to be Swift 6; there was actually a post to the Swift forums just a couple of weeks ago about what it means to migrate to Swift 6, and what the goal is there. When we introduce Swift 6, that’s going to be the version of Swift that introduces data race safety by default.
So we talked about Swift being a memory safe language. The one exception to that is if you have two threads, and you’ve created those two threads, and they share state between themselves. If you mutate a global object from both threads at the same time, that introduces a data race that can introduce memory-unsafe behavior.
As of today, you can opt into a strict mode that will prevent you from introducing those data races into your code. So if you have the latest version of Swift, if you download like the latest toolchain from Swift.org to try out the upcoming version, you can opt into that data race safety checker, and they’ll give you a bunch of warnings saying “Hey, this is a class. You’re escaping it by sending it from this task into this task. That could introduce a data race.” And it’ll tell you, and you can go in and there are various language techniques that allow you to do something about that; unsharing the reference, making a copy, things like that.
[47:57] Swift 6 will turn those warnings into errors, and that means that if you’re starting a new project from scratch, you can be certain that your code is guaranteed data-race free, because the compiler just won’t let you accidentally write a data race. Obviously, like all of these things, there’ll always be unsafe opt outs, where you say “Oh, I’ve got to deal with this legacy API, so I need to be able to tell the compiler. I know, I know, but let me pass this value.”
But obviously, people have existing codebases where they’ve got to ship their app, they’ve got to do an update, they’ve got the latest version of the language, they want to use the latest version of Xcode that comes with the latest version of Swift, but they haven’t got time to go through and address all of those warnings in order to switch to that newer secure mode. And so whenever we introduce a new major version, we always make it an opt-in choice.
So when you compile your code, you say “Compile with the version of the language 5.0”, or “Compile with the version of the language 6.0.” And if you tell the compiler “Compile with the version of the language 6.0”, it will stop you from making these data race issues into your production code. But if you compile with version 5.0, it won’t stop you; you can just get away with them just being warnings, and then you can tackle them at your leisure. And that’s been much better for the community, because it means that they can move forward; we don’t end up getting into the classic Python 2 to Python 3 situation where people are holding back… And you can also do that migration at the module by module level. So you can break up your code and say “Okay, this bit of code I’ve audited, it’s good. I can go to Swift 6 mode. This bit of code - maybe I’m going to do that next month, but in the meantime I need to ship my app and adopt it. Stick with Swift 5 for now and then adopt Swift 6 maybe after I do that.”
That’s cool. Very fascinating. All the places you can run Swift nowadays…
Yeah, we’d really like people to head on to the Swift website, download a toolchain for their platform of choice, and try it out.
Alright, we’ll link up all the things, including those links you sent us, specifically the Arc one; very interesting. And we did not mention, real quick, the Godot engine situation. Maybe we’ll just close with that. This is in a proposal from Miguel de Icaza, of adding Swift as a potential language of choice for the Godot engine. I’m not sure exactly how that would work. Is that a rewrite? Is that just like an extension? Tell us more about what he’s proposing there. This is for gaming.
Yeah, so I saw that Miguel posted his video from Godot Conf to the various social networks, and it was a really exciting talk to see. So the way he sort of cutely characterizes it is he made this, I guess, multimillion-dollar mistake. He’s kind of riffing off of the old saying by Tony Hoare that he made a billion-dollar mistake by introducing null into his first programming language. In this case, Miguel is suggesting that the mistake was popularizing a garbage-collected language into a game framework, in the form of C#, which obviously is a very popular language for writing games in… But then you have to fight with this issue in this really performance-critical segment of the gaming industry with GC pauses.
So he’s proposing using Swift; he’s been a bit of a Swift booster for a while, and it’s great to see him advocating it in new places. I believe his suggestion is that, again, leveraging that C++ interoperability capability. They could start to introduce Swift into different parts of the Godot project. And again, you can make that an incremental thing, because you can just have it interoperate with the existing C++ code. But he’s also written a nice Godot API wrapper that allows you to actually get going with Godot using Swift today… And I’ve actually seen a few folks post to Mastodon with some examples of their game engines written in Swift, which is really cool to see.
Very cool. Well, we’ll link up that talk as well. I’ll go watch that one myself. I like what Miguel has to say. Very, very smart guy, knows what he’s talking about; very convincing in his argumentation. So we’ll link that one up as well. Thanks, Ben. It’s been awesome.
Thanks a lot.
Our transcripts are open source on GitHub. Improvements are welcome. 💚