PodSearch

ATP

ATP Interview: Holly Borla & Ben Cohen

 

00:00:00 ◼   ► All right, how are we starting this? I didn't... You're starting it. I'm starting it. Okay. You're the host, man. All right. Well, here we go.

00:00:04 ◼   ► All right, so hey everybody, we're doing something extremely special today and I am

00:00:11 ◼   ► genuinely exceedingly excited about it. And so I teased last episode that we would have a little

00:00:16 ◼   ► surprise coming up and a little treat is I think what I called it. And it's actually more than a

00:00:20 ◼   ► little treat. It's a big treat. So today we have a special guest, but not one special guest. We have

00:00:26 ◼   ► two special guests. So here we have today Ben Cohen, who is Senior Software Engineering Manager

00:00:31 ◼   ► for the Swift team and Holly Borlow, the Swift Language Engineering Manager. We are in the

00:00:36 ◼   ► presence of greatness and I don't know how we ended up here, but I'm happy about it. So thank

00:00:41 ◼   ► you Ben and Holly for being here. I know I speak for all three of us and saying we are extremely

00:00:45 ◼   ► excited and lucky. So thank you. Thank you very much for having us on. Of course. We interview

00:00:49 ◼   ► interviewees very often. So, well, and actually just this morning I was watching your video,

00:00:53 ◼   ► which was very good. We'll talk about that. But I guess, Holly, if you don't mind, if you would

00:00:58 ◼   ► mind starting, would you give me the nickel tour of who you are and what you do? I mean, I know,

00:01:02 ◼   ► but not everyone knows. So who are you and what do you do for Apple? Sure. Yeah. My name is Holly.

00:01:07 ◼   ► I'm the Engineering Manager of the Swift Language team. Like you just said, my team focuses a lot on

00:01:13 ◼   ► the user-facing language features like the generic system, type inference, and this year our major

00:01:18 ◼   ► focus has been the concurrency model and specifically data race safety and Swift 6.

00:01:23 ◼   ► Before I joined the Swift team, I was a Swift programmer working on Xcode. And before that,

00:01:27 ◼   ► I was a computer science student at the University of Michigan. That's incredible. And Ben? Yeah. So

00:01:32 ◼   ► my name is Ben Cohen and I manage the Swift team overall. So that includes the language,

00:01:36 ◼   ► but also the backend, the optimizer, a lot of the tooling that goes around the language like

00:01:41 ◼   ► code completion and things like that. At Apple, about eight years, I've worked on various parts of

00:01:47 ◼   ► the Swift compiler, including the standard library, the optimizer. And before that,

00:01:51 ◼   ► I was not a compiler engineer. So I was actually working in that sort of FinTech type stuff.

00:01:55 ◼   ► So I'm going to really make Jon happy. I'm going to jump right to the end.

00:02:02 ◼   ► We're not doing follow up then? No, we're not doing follow up this time.

00:02:05 ◼   ► Well, I guess a real-time follow up. How did you end up-- and I'm asking both of you, but Ben,

00:02:10 ◼   ► since you most recently spoke, we'll start with you. How do you end up being a compiler engineer?

00:02:13 ◼   ► Because my perspective as a Swift developer is there's people like me who kind of know what we're

00:02:18 ◼   ► doing. And then there's compiler engineers who really know what they're doing.

00:02:22 ◼   ► It's like a priesthood where you're a programmer and you write the thing. But then if there's

00:02:26 ◼   ► something wrong with the compiler, you're like, oh, it's not my fault. There are people in an

00:02:30 ◼   ► ivory tower somewhere that make this work. And they're crossing over that path. I know there's

00:02:35 ◼   ► lots of advertising for job positions that you don't need compiler experience. Just come be on

00:02:38 ◼   ► the team. We'll teach you. Well, that is true. You do not need compiler experience. And in fact,

00:02:42 ◼   ► I think actually neither me nor Holly had direct compiler experience before joining

00:02:47 ◼   ► the Swift team to work on the language. Does it have a high tolerance for pain?

00:02:51 ◼   ► Actually, I came to Swift through pain from other languages.

00:02:57 ◼   ► That is such a good answer. That is so good. You sure you're not in PR?

00:03:01 ◼   ► So my love for Swift comes from the fact that I have experienced what other languages have to

00:03:07 ◼   ► offer. And I've always been the language enthusiast. And so whether it's Java or C++ or higher level

00:03:15 ◼   ► languages like Ruby or Perl, there's something great about all of these different languages.

00:03:20 ◼   ► But I always felt historically like these languages had compromises. They were either

00:03:24 ◼   ► a little bit too slow because they were more dynamic and scripting based, or they were unsafe

00:03:29 ◼   ► like C++ or really hard to comprehend like C++. It's a true story.

00:03:34 ◼   ► And my background is actually I used to work on trading systems. And performance is really

00:03:40 ◼   ► important in trading systems. And so we used to do a lot of things in C++. But at the same time,

00:03:46 ◼   ► safety is really important in trading systems. You do not want the machine to do the wrong thing.

00:03:50 ◼   ► And so we always used to have this trade off between like C++ and Java. And when I saw Swift

00:03:57 ◼   ► 10 years ago now, I was actually blown away by the fact that it actually managed to find the

00:04:03 ◼   ► sweet spot between those different things. It was deterministic. It didn't have a garbage collector.

00:04:07 ◼   ► But also it had that higher level feel. It does sometimes look a lot more like

00:04:11 ◼   ► sort of the Ruby-like language where it's really joyful to program in. And it's really great to see

00:04:17 ◼   ► that realized in things like Swift UI where it brings back that joy of programming that I think

00:04:21 ◼   ► sometimes we lose a little bit. And so that was what brought me to Swift. And I joined Apple

00:04:25 ◼   ► originally. I was actually a library developer. So I didn't have that background in compilers,

00:04:30 ◼   ► but I did have that background in writing algorithms and data structures and things

00:04:33 ◼   ► like that. And that was a really nice route in. And from that, I learned about compiler performance.

00:04:38 ◼   ► And from that, got more into the general language design. And that's how come I ended up here.

00:04:43 ◼   ► And then Holly, you said you started working in Xcode. Is that right? And then kind of

00:04:47 ◼   ► meandered from there. What was that story like? Yeah, that's right. So I actually signed up for

00:04:52 ◼   ► a mentorship program that the developer tools organization offered. And they deliberately

00:04:57 ◼   ► paired mentees up with mentors from different parts of the organization so that you could get

00:05:03 ◼   ► to meet people who you didn't work with on a day to day basis. And I got paired up with a Swift

00:05:07 ◼   ► compiler engineer. And that sort of sparked my interest in actually joining the team. So for me,

00:05:13 ◼   ► I feel like I became a compiler engineer by accident. What brought me to developer tools at

00:05:18 ◼   ► Apple is I was really interested in education for programming. I also ended up studying computer

00:05:23 ◼   ► science sort of by accident. I didn't go into university knowing anything about programming

00:05:28 ◼   ► or computer science like a decade ago today. You know, it's Swift's 10 year anniversary.

00:05:33 ◼   ► 10 years ago, I knew nothing about programming. I was graduating high school, set to study dance

00:05:40 ◼   ► at the University of Michigan. And engineering was sort of my backup and all engineers have to

00:05:45 ◼   ► take a programming class and I really enjoyed it. And that, I think, for me really showed the power

00:05:52 ◼   ► of making Swift or not Swift, making programming more approachable to people who weren't exposed

00:05:58 ◼   ► to that previously. So I thought working on developer tools was a good way to do that. And

00:06:05 ◼   ► that was how I started to learn Swift when I joined the Xcode team. The part of Xcode that I

00:06:10 ◼   ► worked on had just been entirely rewritten in Swift. So yeah, it was this series of opportunities

00:06:17 ◼   ► that led me to really becoming interested in working on the Swift language itself. And now

00:06:21 ◼   ► this is sort of the ultimate opportunity to make programming more approachable to people who have

00:06:27 ◼   ► an idea and are interested in bringing that to life through code. I love that. And I'll throw Marco

00:06:34 ◼   ► under the bus with me because I can tell you that Marco and I went to school for CS and computer

00:06:38 ◼   ► engineering and I cannot fathom a situation where engineering is like my fallback. Like, oh,

00:06:43 ◼   ► I'm sure I'll be fine in engineering if this other stuff doesn't work. That's incredible.

00:06:47 ◼   ► I just couldn't dance. That was my problem. I think I'll hear stories like an afterschool

00:06:51 ◼   ► special of how you can slippery slope into the seedy world of compiler engineering.

00:06:55 ◼   ► You start out as a promising dancer, but somehow the compiler people got her. And now look at her.

00:07:00 ◼   ► Now I'm going to continue to make Jon upset by continuing to be at the bottom of the document,

00:07:04 ◼   ► but I promise Jon, I will come back up to the beginning.

00:07:07 ◼   ► At least you're in the, I'm about to ask him if he's not even in the documents.

00:07:09 ◼   ► You're doing great. We have a structure. We're sticking to it.

00:07:11 ◼   ► Well, this is our structure, despite what Jon said.

00:07:15 ◼   ► It's not copyable. Jon, have you heard the show?

00:07:17 ◼   ► Right. So Ben, you were very rightfully, in my opinion, slagging on C++ just a few minutes ago.

00:07:25 ◼   ► Guess what the Swift compiler is mostly written.

00:07:27 ◼   ► Well, that's exactly what I was going to say. So last I remember hearing,

00:07:30 ◼   ► the Swift compiler, the last I looked, the Swift compiler is largely, if not entirely, C++.

00:07:34 ◼   ► So you're pointing at me, wait, wait, there's more. So tell me, is there more?

00:07:39 ◼   ► There is more. So the compiler, I actually don't have the right percentage.

00:07:42 ◼   ► It's actually slightly difficult to tell because if you look at the GitHub repo,

00:07:47 ◼   ► it gives you lies because for two reasons. One is like, we have a lot of tests written in Swift

00:07:52 ◼   ► and those shouldn't count. But also we have started the process of writing parts of the compiler in

00:07:59 ◼   ► Swift. And that started quite a while ago now, I think maybe four years ago now. But when we do

00:08:06 ◼   ► that, we actually, we create those bits of the compiler that we rewrite as packages. And when

00:08:10 ◼   ► you do that, we break them out into a separate repo. So if you go to github.com/apple for now,

00:08:16 ◼   ► soon, swiftlang/swift-driver, that was the first part of the Swift compiler that we started

00:08:23 ◼   ► rewriting in Swift. That happened about four years ago. And the driver is basically the way into the

00:08:29 ◼   ► front end of the compiler, right? So it's the thing that does the initial processing of your

00:08:33 ◼   ► command lines, and it organizes the build and things like that. That was written in Swift.

00:08:37 ◼   ► Two years ago now, we started rewriting the parser in Swift. And so that is actually part of a wider

00:08:44 ◼   ► project called Swift Syntax, which is itself written in Swift, which is originally a way of

00:08:48 ◼   ► just manipulating Swift code. It was a library for manipulating Swift code. And that evolved into a

00:08:54 ◼   ► replacement for our current C++ parser. That is actually the foundation for macros. So last year,

00:08:58 ◼   ► when we introduced macros, those are based around Swift Syntax and the Swift parser.

00:09:02 ◼   ► We have some ongoing work that's happening at the moment to do the next layer down, which is what's

00:09:09 ◼   ► called AST generations. So what you do is you parse the code and then you turn it into an abstract

00:09:13 ◼   ► syntax tree. And then you have to lower that down into the underlying representation. That is

00:09:18 ◼   ► ongoing at the moment. And once we've done the AST gen layer, we will actually be throwing away

00:09:24 ◼   ► the C++ parser. Now that's going to be an interesting moment, because that is the

00:09:30 ◼   ► point at which there is no way back. That is the point at which you will need a Swift compiler to

00:09:34 ◼   ► build Swift. You know he's going to look back and then get history. It's still there, sort of.

00:09:38 ◼   ► Well, it is actually. It's an interesting thing, because we have-- app developers sometimes point

00:09:44 ◼   ► out that they have to wait a year or two before they can raise the minimum deployment target in

00:09:48 ◼   ► order to use SDK features. We as compiler authors know that pain, because we cannot use the very

00:09:56 ◼   ► latest Swift features when implementing the Swift compiler, because you have to be able to use the

00:10:01 ◼   ► shipping compiler in order to bootstrap. So we're very familiar with that. But yeah, and then more

00:10:07 ◼   ► recently than that, we have started writing optimizer parses in Swift. So that is actually

00:10:13 ◼   ► using C++ interop, which is another important feature of Swift. We obviously interoperate with

00:10:18 ◼   ► LVM, which is written in C++. And we use that to build our optimizer parses to do things like

00:10:24 ◼   ► hoist variables out of loops and things like that. And those are now written in Swift as well. So

00:10:29 ◼   ► we are getting there. It'll be a ways away. It's not our main goal. We don't rewrite things for

00:10:36 ◼   ► the sake of it, even though it's written in C++. It's working. And so really, when we decide we

00:10:42 ◼   ► want to do something where we want to rewrite a part of the compiler, we try to make it for a good

00:10:46 ◼   ► reason. And those good reasons can be, for example, creating a macro system with a nice, friendly

00:10:52 ◼   ► Swift API. Or when we rewrite the optimizer parses, we usually do it in order to simplify them

00:10:58 ◼   ► and make them more effective. Yeah, so we are on that path to self-hosting.

00:11:04 ◼   ► But it's going to feel really good when you have to delete that code, though.

00:11:07 ◼   ► It feels very good to delete code. So, Bill, I'm not sure which one of you is more appropriate to

00:11:12 ◼   ► answer the following. But building on that, it certainly seems the implication is there is a

00:11:16 ◼   ► strong interest to become self-hosted. And I'm not sure I'm the best person to summarize that. But

00:11:22 ◼   ► basically, the Swift compiler is written in Swift, right? And is it fair to say the eventual-- I'm not

00:11:27 ◼   ► looking for a date-- but the eventual one sometime goal would be to self-host entirely, if possible?

00:11:32 ◼   ► Is that fair to say? We don't comment on future products.

00:11:35 ◼   ► Yeah. Well, this is not a product. This is the Swift language that is entirely open source.

00:11:40 ◼   ► And we are perfectly liberty to comment on. So, yes, I think the ultimate goal is that the compiler

00:11:44 ◼   ► should be written in Swift. If nothing else, it does improve the safety of the compiler.

00:11:50 ◼   ► The compiler is not filled with segfaults. But they can happen. And obviously, rewriting parts

00:12:00 ◼   ► of it in Swift eliminate that possibility because it's a safer language. And so that's one benefit

00:12:06 ◼   ► that comes from it as well as bringing other features. The other benefit is it makes it more

00:12:09 ◼   ► approachable for outside people. I mean, you were talking about working on the Swift compiler as if

00:12:13 ◼   ► it's a very intimidating thing. But at the end of the day, it's actually kind of pretty straightforward

00:12:18 ◼   ► code when you look at a small part of it, right? When you look at a particular optimization pass,

00:12:22 ◼   ► you know, you can usually see pretty much what it's doing. And it's actually

00:12:25 ◼   ► a great opportunity to get contributors involved. I know Holly's worked with quite a lot of

00:12:30 ◼   ► people who come new to the Swift programming language as well. Yeah, we also organize a

00:12:34 ◼   ► mentorship program called the Swift mentorship program, where open source contributors who are

00:12:40 ◼   ► interested in contributing to various parts of the Swift project, including but not limited to

00:12:43 ◼   ► the compiler, they sign up, they get paired with someone who regularly contributes to the compiler,

00:12:48 ◼   ► and they work together for 10 weeks on open source contributions. And a lot of people, I find that a

00:12:54 ◼   ► lot of people who write Swift, who are iOS developers are really interested in making

00:12:59 ◼   ► some contributions to the compiler, just as a learning experience or better understanding,

00:13:03 ◼   ► you know, how their code works. If you're in the depths of how, you know, type inference or the

00:13:10 ◼   ► actor isolation checker works, it gives you a little more knowledge into, you know, how the

00:13:15 ◼   ► compiler sees your code when you're writing Swift code. So yeah, it's a cool program and a really

00:13:20 ◼   ► good learning experience for people who are writing Swift. And I completely agree that

00:13:25 ◼   ► moving more of the compiler over to Swift will make contributing to the compiler a lot more

00:13:29 ◼   ► approachable for people. Does that include the standard library? Like if someone wants to add

00:13:32 ◼   ► a method that says first, second, third spelled out fourth, fifth, sixth, and you stop them when

00:13:37 ◼   ► they get to 30 seconds, like that's all Swift code in the standard library. So you can contribute to

00:13:41 ◼   ► that and say, hey, I contributed to the Swift language, but you're just making Swift methods in

00:13:44 ◼   ► the library. So I'm curious, you know, and probably for Holly, as we go into this new

00:13:49 ◼   ► era of Swift concurrency and data race safety and everything, Swift I think has always struck

00:13:57 ◼   ► an interesting balance. I think it's kind of a roller coaster. Sometimes it's more successful

00:14:01 ◼   ► than other times at this balance of being easy to use for non-experts or newbies to a language

00:14:08 ◼   ► or just new programmers. And also having all this power behind it and having quite a bit of

00:14:14 ◼   ► complexity behind it. And as we go into this new data race safety era, how do you strike

00:14:23 ◼   ► that balance? You know, obviously these are some very advanced concepts and somebody might get some

00:14:28 ◼   ► warning as they're building their code saying something's not sendable because it has mutable

00:14:32 ◼   ► state and they might not even know what any of that means. How do you balance that with

00:14:37 ◼   ► being approachable to new programmers or to less experienced programmers?

00:14:40 ◼   ► Yeah, so the goal for concurrency is really similar to what we've accomplished with other

00:14:46 ◼   ► advanced features of the language. Like the generic system is the one that I always go to,

00:14:50 ◼   ► because from the very first lines of code that you write in Swift, you're using the generic system

00:14:55 ◼   ► because you're using standard library types like Array or you're using frameworks like Swift UI,

00:15:00 ◼   ► which are really heavily leveraging these advanced features to make APIs that are really natural to

00:15:06 ◼   ► use for programmers. But you don't need to understand generics, you don't need to understand

00:15:10 ◼   ► how it works until you're at a point where you need to use those advanced features in your own

00:15:15 ◼   ► code. And that's the end goal with concurrency as well. For newcomers to app development or

00:15:21 ◼   ► newcomers to Swift, when you're writing code, by default that code should be on the main actor,

00:15:26 ◼   ► and you shouldn't have to actively think about the fact that that code is on the main actor

00:15:31 ◼   ► until you're trying to actively introduce concurrency into your project. And at that point,

00:15:38 ◼   ► you know, you'll be confronted when you make a mistake that can lead to a data race in your code.

00:15:41 ◼   ► And I think that both the progressive disclosures is the way to make that complexity more

00:15:47 ◼   ► approachable. But I also think introducing those checks at compile time will also make learning to

00:15:56 ◼   ► write concurrent code a lot more approachable for people who are new to concurrency in general.

00:16:01 ◼   ► And this is a continued evolution of making concurrent programming more approachable.

00:16:05 ◼   ► Concurrent programming is just notoriously really hard to get right. I don't know if you've ever

00:16:10 ◼   ► debugged a data race before, for those of you who are listening, but if you have, you know that it

00:16:14 ◼   ► can take days or even weeks. And the introduction of dispatch even was a huge step forward for

00:16:21 ◼   ► making concurrent code easier to write. Working with dispatch queues is way easier than managing

00:16:27 ◼   ► low level system resources like threads manually in your app. But you still have to know when to

00:16:33 ◼   ► apply those tools to protect mutable state in your code. And with data race safety in Swift6,

00:16:38 ◼   ► you can't get it wrong. The compiler will tell you if there's a risk of a data race in your code.

00:16:45 ◼   ► And having to confront those concepts at the point when you make a mistake is better for

00:16:54 ◼   ► forming a mental model of how concurrent code should be written in your project.

00:16:57 ◼   ► So I'm really excited for people to start to learn concurrency for the first time with data

00:17:03 ◼   ► race safety in Swift6, as opposed to I think a lot of people right now have internalized how

00:17:07 ◼   ► to use dispatch and they've been using that for many years and now they're trying to learn this

00:17:11 ◼   ► other like, it's not a completely different system in how you write code, but it is different in how

00:17:17 ◼   ► you approach it and at what point you're confronted with the issues. And I think that might be a

00:17:21 ◼   ► little bit more difficult than learning concurrency for the first time with the compiler checks in

00:17:25 ◼   ► place to help prevent you from making mistakes. Is that how you characterize like the difference

00:17:29 ◼   ► between the Swift concurrency and the like the predecessor concurrency systems at Apple? Like

00:17:33 ◼   ► we've had, um, your grand sales were dispatch, the dispatch queues, NS operation queue, but

00:17:38 ◼   ► pthreads back in the day, locks of various kinds over the years. And all of those were kind of,

00:17:45 ◼   ► you'd have sessions on and they'd say, here's how you properly use this. Here's how many

00:17:48 ◼   ► cues you should have and stuff like that. But it was all sort of like runtime stuff and everything

00:17:52 ◼   ► I hear about Swift concurrency is always, we will do these checks for you at compile time so that

00:17:56 ◼   ► it runs on, you don't have to run your thing to see if there's a problem or like audit the code

00:18:01 ◼   ► and look over it. This is like the compiler will check it for you and make sure it's mostly okay.

00:18:06 ◼   ► Would you say that's the big difference? Yeah, absolutely. You should be able to program by

00:18:10 ◼   ► bumper where, um, you know, the compiler is there to tell you like, Oh no, you got this a little

00:18:14 ◼   ► bit wrong with actionable suggestions for how to fix that code. Yeah. So you're talking about

00:18:18 ◼   ► the progressive disclosure and like you don't have to know about this until you start introducing

00:18:21 ◼   ► concurrency. But I feel like, uh, that's true of the Swift language if you're writing just Swift

00:18:26 ◼   ► code, but once they have everyone else in this company makes a bunch of frameworks and those don't

00:18:30 ◼   ► know or care about Swift concurrency for the most part. Uh, and they're in your code and you think,

00:18:36 ◼   ► I haven't introduced any concurrency, but it's like, well, this method has a callback and it is

00:18:41 ◼   ► cranky now. And you're like, but why I don't, I didn't make that API. It's, it's complaining

00:18:46 ◼   ► about something that I don't understand. It's not an API that I wrote. And so you're like,

00:18:50 ◼   ► you're faced with this dilemma of just, you stare at it for awhile. It's like, should I not use that

00:18:55 ◼   ► API? Should I, should I, you know, like I think we've all had experience in everyone you've

00:19:00 ◼   ► probably talked to has had experience trying to enable stricken currency in five 10. So if I,

00:19:04 ◼   ► you know, and you set the setting and I go, you see all the warnings and you're like,

00:19:07 ◼   ► how far away am I really? You're like, how many? And you know, and I think we've all taken

00:19:11 ◼   ► different swings at this, like, and I've seen you both sort of counter the conventional wisdom.

00:19:15 ◼   ► It's like, well, I'll just make everything sendable and that will fix everything,

00:19:17 ◼   ► but that doesn't work. And so you're like, well, maybe I can just add annotations. I'll put me

00:19:20 ◼   ► an actor on a bunch of things, but that doesn't work. And it's like, well, maybe I'll just

00:19:23 ◼   ► sprinkle assume isolated everywhere. That's probably not the right approach. And I think

00:19:27 ◼   ► my personal experience is I've taken like four different runs at bringing one of my apps on

00:19:31 ◼   ► just stricken currency. And I just keep backing off and scratching my, I know there's a WWC session

00:19:35 ◼   ► about it and I haven't seen it. My bad. It was a busy day yesterday and it's migrating to Swift.

00:19:40 ◼   ► But I feel like that is a lot of the barrier and it's nothing to do with the language.

00:19:42 ◼   ► It has to do with the APIs that we're using that were created, you know, decades ago

00:19:46 ◼   ► that have their own conventions and stricken currency. And it's not wrong. It's correct.

00:19:50 ◼   ► There is a potential for immutable state to be messed up there. And then of course,

00:19:54 ◼   ► even in our own code, it's like, well, I use cues for this and I use locks and I'm

00:19:57 ◼   ► pretty sure it's safe, but stricken currency says, well, that's what unchecked sendable is for.

00:20:01 ◼   ► Yeah. But that's the whole thing. Like you don't want to go through it and sprinkle it through

00:20:05 ◼   ► says, I'm sure this is okay. I'm sure this is okay. Like there are annotations to do that,

00:20:09 ◼   ► but all you're doing is undercutting yourself by saying, no, I'm totally sure the code I wrote

00:20:12 ◼   ► last year is bug free and there is no races and it will satisfy the compiler, but you haven't

00:20:17 ◼   ► actually solved the problem. You haven't actually used the system you're saying, which is you should

00:20:20 ◼   ► be able to write it. The compiler tells you what it's wrong. You might as well just turn that

00:20:24 ◼   ► mode off. So, I mean, I think a lot of users find it frustrating, but it is a difficult problem. And

00:20:28 ◼   ► I, I'm assuming, well, you tell me what you think the correct approach is. Give me the three second

00:20:33 ◼   ► summary of the session that I didn't watch. I'll let Ben do that. It's Ben's session.

00:20:38 ◼   ► It is. And well done for Casey for getting ahead of John and watching it already.

00:20:42 ◼   ► So it really partly depends on what kind of frameworks you're using and it's possible that

00:20:47 ◼   ► you're using some frameworks that, that, that make it harder or easier depending on what kind of code.

00:20:53 ◼   ► Mac framework. Right. Oh, you're screwed.

00:20:56 ◼   ► So for example, the UI layer we've actually, and it's worth trying the new SDK because

00:21:04 ◼   ► at the UI layer, there's been a lot of work to indicate which parts of Swift UI also UI kit and

00:21:10 ◼   ► the app kit are by definition always supposed to be running on the main thread. And that should

00:21:16 ◼   ► actually, for people who've tried five 10, it's well worth downloading the newest decay and giving

00:21:20 ◼   ► that a go. Does that also include like, I know this is a documentation issue, but often you'll

00:21:24 ◼   ► see a thing with a callback and you have a question. It's like, what thread will the

00:21:28 ◼   ► callback run on? And you're just like, Oh, you're just supposed to know whatever you thread you, you

00:21:31 ◼   ► register it on. That's the thread the callback will run on, but you don't see that in the

00:21:34 ◼   ► documentation. So you're like, well, I, I registered for this on the main thread. And when the callback

00:21:39 ◼   ► gets called, it will probably get called on the main thread. And sometimes they take a queue

00:21:42 ◼   ► as an argument and you just have to know that the main queue is the same as the main thread. But

00:21:45 ◼   ► like documentation wise, I always feel like I look up one of these old app kit things and I'm just,

00:21:50 ◼   ► it's guesswork. Right. Did you know, John, I learned this morning that there is a keyword

00:21:55 ◼   ► there. What is it? It's a assume, assume main thread. There it is. I couldn't quite get there,

00:22:01 ◼   ► but there's tools for this. John, as it turns out, I know, but I know that's not a tool for that.

00:22:05 ◼   ► Right. Yeah. As soon as I say it, all it's going to do is, is you throw a runtime error when you're,

00:22:10 ◼   ► when it finds out it's not on the main thread scenario. Right. Just dispatch it to me.

00:22:14 ◼   ► So it, it, so assume isolated does throw a runtime error when, uh, when you're not on the main

00:22:20 ◼   ► thread, this is actually something that a lot of good programmers are already doing, which is like,

00:22:24 ◼   ► they put in preconditions where they, they know this is supposed to be on the main thread. Um,

00:22:28 ◼   ► and they put in a precondition just in case they call it from somewhere else in their app where

00:22:31 ◼   ► it's, they're getting a call from a dispatch queue. That's, that's not isolated to the main,

00:22:35 ◼   ► uh, the main thread. And, and that can lead to trouble. Um, I think, uh, somebody was saying

00:22:40 ◼   ► earlier, um, you know, you run your program and you find out it doesn't quite work. Um,

00:22:44 ◼   ► as opposed to a compile time, you find out that you need to do something. Yeah. It feels like

00:22:47 ◼   ► it's undercutting the bumper thing. Holly was saying is like, I don't, I don't want to find

00:22:50 ◼   ► out at runtime. So every time I do assume isolated, I'm like, there's must be a better way.

00:22:54 ◼   ► Don't use that there, man. That's not what it's for. So I would say that, um, finding out at

00:22:58 ◼   ► runtime that your code is broken is the best case scenario under the old world, right. Which is that

00:23:04 ◼   ► you, you, you really, you hope to find out when you run your code, right. That something is wrong.

00:23:08 ◼   ► But what actually happens is that, um, in, uh, in some of these, uh, uh, techniques, you, you find

00:23:16 ◼   ► out in the wild in when your program is crashing and you do not exactly know why. Um, I'm, I'm

00:23:21 ◼   ► always amused by people that make these jokes on, on Mastodon or Twitter where they, they say like,

00:23:25 ◼   ► they make a joke about concurrency where they jumble up the words. Um, and that's cute, but

00:23:30 ◼   ► that is again, the best case scenario is jumbled up words. That's very benign. What's worse is like,

00:23:35 ◼   ► you know, you crash, you corrupt user data. This is, this is no good. Um, and so, um, that's why

00:23:40 ◼   ► a lot of people have these really great practices in, in the old world of dispatch, um, where, uh,

00:23:45 ◼   ► they will insert like these assertions saying, I, I'm, I want you to stop me if I'm, if I'm not

00:23:50 ◼   ► running on the main queue. Um, so I think the, the longterm goal is that we need to lift these kind of,

00:23:56 ◼   ► um, uh, this information out of documentation. We want, want to take it out of documentation

00:24:01 ◼   ► and put it actually in the definition of the API. It's not in the documentation now,

00:24:05 ◼   ► so you don't have to lift it up. So, um, uh, so the, um, the benefit of putting it there

00:24:13 ◼   ► so that the compiler actually enforces it is that you can't not have that information,

00:24:17 ◼   ► right? The, by definition, your code, uh, does encapsulate the information about where you are

00:24:22 ◼   ► running and how it's running. Yeah. Cause one of the things I do when flailing is like, there's

00:24:25 ◼   ► a callback and I'm like, can I just annotate the callback as main actor? And the answer is no,

00:24:29 ◼   ► you can't. And then, and then it's like, why is it already on always on the main thread is, is,

00:24:35 ◼   ► you know, I figured what the error is. I'm just waiting for the framework to update with

00:24:38 ◼   ► async calls. You don't have all the time in the world to wait. And yeah, it's, it's what it comes

00:24:43 ◼   ► down to. Like you mentioned queues, right? So I, I, one of my apps has concurrency. I'm sorry. It

00:24:47 ◼   ► does. Um, and, uh, I use queues and in one situation I wrote a little class and I use locks,

00:24:53 ◼   ► the old, old style locks and pretty sure it's probably okay. Uh, but I look at that and like,

00:24:58 ◼   ► I would like to use Swift concurrency because then I would be a feel more sure,

00:25:02 ◼   ► but there's nothing you can do to sort of annotate or markup dispatch queues or locks. And other than

00:25:07 ◼   ► than the reassurance of just telling the compiler, I'm pretty sure that I'm right. I would rather

00:25:11 ◼   ► just like pull that out and re implement it with actors and so on. And that sometimes just

00:25:17 ◼   ► seems daunting. So, um, another thing that there's a ton of Swift code out there and Swift code that

00:25:23 ◼   ► inter operates with C based languages like objective C and C plus plus. Um, we're at the

00:25:28 ◼   ► start of this transition to start to integrate Swift's native, safer concurrency primitives into

00:25:35 ◼   ► these like vast code bases that are using older, you know, library based concurrency primitives

00:25:40 ◼   ► like dispatch queues. Um, the system is designed for incremental migration. Um, so in the case,

00:25:45 ◼   ► if you have like a class backed by a dispatch queue, there is a technique that you can use to

00:25:50 ◼   ► turn that class into an actor that's backed by a dispatch queue. Um, it uses a fancy feature called

00:25:57 ◼   ► custom actor executors, but the way to do it, it's only like four or five lines of code that you

00:26:01 ◼   ► actually have to write in your own code. And what that lets you do is from your Swift code, it lets

00:26:05 ◼   ► you use the static actor isolation, um, and not have to mess with the dispatch queue. But when

00:26:10 ◼   ► you're interacting with API APIs that are based on dispatch queues, you can still pass the dispatch

00:26:15 ◼   ► queue there. And then you can bridge between like the dynamic isolation in the static world with

00:26:20 ◼   ► tools like assume isolated. That brings up another question of like a incremental adoption. I know.

00:26:25 ◼   ► So this Swift six just came out. Um, and, uh, in the old five world, we had the little setting to

00:26:30 ◼   ► set it on complete concurrency, whatever. I know there's a whole bunch of features in Swift six and

00:26:34 ◼   ► new things for sustainability and everything that make it easier. But what is the, what is the

00:26:38 ◼   ► mechanism in your project of saying like, I want, you know, is it, is it per module? Is it per file

00:26:44 ◼   ► to saying I want the Swift six language features, but this file is not ready for stricken currency.

00:26:48 ◼   ► What does that look like? So the, yeah, the setting is per module. So in your X code build settings,

00:26:54 ◼   ► there's a language version setting, or if you're in a Swift package manifest, there's an API for

00:26:58 ◼   ► setting it per target. And you, um, many people currently have that set to something, whether it's

00:27:03 ◼   ► four, 4.2 or five. Um, so you would change that to six for the specific module that you're looking to

00:27:10 ◼   ► migrate to Swift six. And then if you have a particular file that, um, violate some of the

00:27:16 ◼   ► rules in ways that are really difficult for you to change, um, there are ways to opt out of checking

00:27:21 ◼   ► in in specific areas in your project, um, using things like pre concurrency import statements.

00:27:26 ◼   ► If it, if the issue is in an API that you're using, um, or, um, tools like non-isolated unsafe,

00:27:32 ◼   ► if you have, for example, like a global variable that you're manually guarding with a lock or a

00:27:37 ◼   ► queue at the point when you access it, you can use non-isolated unsafe to opt out of the compilers

00:27:42 ◼   ► checking there. So there are a variety of tools like that to let you opt out of the checking in

00:27:45 ◼   ► narrow situations in your code. Um, and then those are also things like handles that you can audit

00:27:50 ◼   ► for later, um, to actually take a look at the opt-outs that you're using in your code and try to,

00:27:55 ◼   ► um, uh, use those as refactoring opportunities to, um, rewrite some of that code to use something,

00:28:01 ◼   ► something safer. So you're picking the Swift six as the language and that includes everything

00:28:05 ◼   ► having to do with Swift six when you pick, no, no. So, so Swift six, the language mode,

00:28:10 ◼   ► where you go into the X code settings and you, you say language mode of Swift six, that purely

00:28:15 ◼   ► governs the strict concurrency checking. So the Swift six compiler that you get with the latest

00:28:20 ◼   ► X code that has all of the new features. So I think you've made a glancing blow to, uh,

00:28:25 ◼   ► non-copyable types. Um, those features are available. Um, new generic capabilities,

00:28:30 ◼   ► non-copyable types are available in the Swift six compiler. You do not need to tell you,

00:28:34 ◼   ► you would pick the Swift five language mode, but it's using the Swift six compiler to run

00:28:38 ◼   ► in Swift five language mode. You get non-copyable types. You don't get the strict concurrency.

00:28:41 ◼   ► That's right. And that's exactly, this is part of a journey that the entire Swift ecosystem needs to

00:28:45 ◼   ► go through. Um, so, um, uh, being ready for Swift six, having your dependencies ready for Swift six.

00:28:51 ◼   ► Um, there's actually a swift package index.com, uh, which is this great website. They have a,

00:28:56 ◼   ► a tracker now that tells you which packages they are compiling that build cleanly on the

00:29:01 ◼   ► Swift six pod. But, um, it really does depend on the nature of your program and whether your

00:29:05 ◼   ► dependencies are now ready for Swift six, whether you want to turn on that language mode. And this

00:29:10 ◼   ► dates back to, um, we've been doing this now since the Swift four days. So, um, uh, since we

00:29:16 ◼   ► introduced the Swift four language mode, we've always had this source compatibility guarantee

00:29:21 ◼   ► promise that whenever you download the new compiler, um, uh, with a couple of exceptions

00:29:26 ◼   ► where like maybe there are a couple of issues with your code where maybe the code was like

00:29:31 ◼   ► explicitly incorrect. Um, we always want you to be able to compile your code as is with the latest

00:29:37 ◼   ► compiler. And then when you're ready for some breaking change, uh, there were a few in Swift

00:29:42 ◼   ► five and obviously in Swift six, the, the, the key key change here is strict concurrency. You're then

00:29:47 ◼   ► able to turn it on, on a per target basis. Is that like a, a, a long standing kind of marketing

00:29:53 ◼   ► decision to tie them to the, I mean, you're just deciding that Swift six means stricken currency.

00:29:57 ◼   ► You could have, for example, it said Swift six just means Swift six language features and there's

00:30:00 ◼   ► some other option for stricken currency. And he said, no, we're tying, we're tying this feature

00:30:04 ◼   ► to this number because people want the higher number. Is that like a, a sort of a, uh, social

00:30:09 ◼   ► engineering decision or it's, it's a way of thinking about like the forward progress. I mean,

00:30:13 ◼   ► you don't want to be stuck in this world, um, with the Python two, two to three transitions style

00:30:18 ◼   ► thing, right? Where those were tied to, um, uh, you know, updating your compiler and then you

00:30:23 ◼   ► couldn't get the new stuff without changing your code to adapt to the way that the new language

00:30:28 ◼   ► works. So it's this, this way of helping engineer the ecosystem to help have this continuous forward

00:30:34 ◼   ► progress. But at the end of the day, people also, um, you know, some people have written code in

00:30:38 ◼   ► such a way that it won't be so easily adapted to Swift concurrency. Some people have written code

00:30:42 ◼   ► using a lot of new frameworks, um, and a lot of, uh, async await and the path for them is actually

00:30:48 ◼   ► pretty clean. And so we want people to be able to opt into that. Um, the choice as to whether you

00:30:53 ◼   ► opt in or not is up to you. If you're finding that you are experiencing quite a lot of, uh,

00:30:58 ◼   ► pretty gnarly crashes, it's probably worth considering opting in. Um, one great time to opt

00:31:03 ◼   ► in is if actually you want to start introducing a lot more parallelism into your code, right? So

00:31:08 ◼   ► we have these powerful new devices. They have many cores. Um, and you might find yourself with an app

00:31:14 ◼   ► that previously was doing most of its work on the main thread with a little bit of background

00:31:17 ◼   ► processing, but you really want to take advantage of a lot more parallelism in your code. That will

00:31:21 ◼   ► be a great time to turn on Swift six mode in order to know that you can do those refactorings, uh,

00:31:27 ◼   ► without fear introducing new data races. Um, so yeah, it's really up to each individual project

00:31:33 ◼   ► to make that decision and to see how, uh, how the community is moving forward with them in order to

00:31:38 ◼   ► to update their dependencies and then, and then take the plunge. Do you worry about like releasing

00:31:42 ◼   ► Swift version 10 many years from now and huge code bases are still in Swift five language mode.

00:31:49 ◼   ► Like they're using a Swift 10 compiler to run Swift five language mode because they could never

00:31:52 ◼   ► get the wherewithal to, to go stricken currency compliant. And you're just plowing bravely forward

00:31:57 ◼   ► here at Apple for making version after version. And they're all great, but they can never cross

00:32:00 ◼   ► the six threshold because they can never get their code to run under stricken currency. The millions

00:32:05 ◼   ► of lines of like dispatch queue and manually created locks. Like you worry about hindering

00:32:09 ◼   ► your parts. You've basically made a hard gate of like, look, you're not going to be running a Swiss

00:32:13 ◼   ► seven, uh, next year or whenever, if you can't go stricken currency and you're like, well, my reason

00:32:18 ◼   ► I can't go is cause we have 10 million lines of, you know, manually managed locks or something.

00:32:22 ◼   ► So, um, it really only governs a handful of things. So that is the goal is always,

00:32:27 ◼   ► whenever we introduce a new language feature that you do not have to update to the new language mode.

00:32:31 ◼   ► We were looking at somebody's project yesterday where they were still on Swift four mode.

00:32:35 ◼   ► Um, and really there was not that much they were missing out on. Um, uh, so we have this longterm

00:32:41 ◼   ► promise to always, uh, always support those, those language features, um, so that people

00:32:46 ◼   ► aren't forced to update. Um, but like I say, most of the language features themselves are not gated

00:32:51 ◼   ► on the language version. And so, um, really it's only one we need to take these big step forwards,

00:32:57 ◼   ► um, that we, uh, encourage people to, to upgrade. They'd be running in Swift five language mode,

00:33:03 ◼   ► but they'd still have access to all the new Swift 10 features, but they would feel bad about

00:33:06 ◼   ► themselves because their number is five and you're rolling out seven and eight and nine and 10 and

00:33:11 ◼   ► people be out. They'd look at the little gamified badge on the Swift package index and like, you

00:33:14 ◼   ► don't have the little things as Swift 10 compliance. And I have a little star next to my package and

00:33:17 ◼   ► you don't like, I get the language features. It's just not compliant. I also think there's

00:33:21 ◼   ► a misconception that you need to totally eliminate all of the uses of tools like locks and dispatch

00:33:28 ◼   ► cues in order to migrate to Swift six. I don't think that's true. Um, I think locks, I mean,

00:33:32 ◼   ► um, Swift, the Swift six standard library includes a new, um, primitive, uh, mutual exclusion lock

00:33:38 ◼   ► called mutex. And that is a tool that people can and should use in some scenarios in their code.

00:33:43 ◼   ► And I know there are a variety of other lock types out there that people are currently using.

00:33:46 ◼   ► You don't need to stop using those types, um, in order to migrate your code base to, um, the

00:33:52 ◼   ► Swift six language mode. The same thing is true of dispatch cues. And, um, like I said, part of the

00:33:56 ◼   ► reason why the system is built on incremental migration is because we know there's so much

00:34:01 ◼   ► concurrent code out there that is using, um, you know, dispatch and other concurrency primitives.

00:34:07 ◼   ► And if you had to eliminate or just totally refactor all of your code in order to migrate

00:34:12 ◼   ► to Swift six, nobody would ever do it. Um, so I don't think you need to actually like massively

00:34:18 ◼   ► refactor your code in order to migrate to Swift six. Though in some cases, like in Ben's talk,

00:34:22 ◼   ► you'll see, um, a talk that he gave back in 2021, he actually took a sample app and, um,

00:34:28 ◼   ► it was using dispatch and he went through and, um, replaced some uses of dispatch cues with actors.

00:34:33 ◼   ► And that might make the migration, um, a little bit easier in some cases. Um, but you'll, you'll

00:34:39 ◼   ► sort of see when, when you watch the talk, um, some of the things that are made easier by

00:34:43 ◼   ► introducing actors in some places, but it is still possible to do it if you're using other things

00:34:47 ◼   ► like dispatch to use. I've seen that talk. One of the challenges there is, um, uh, that doing that

00:34:53 ◼   ► refactoring prior actually made it a lot easier to migrate to Swift six. And that's actually something

00:34:58 ◼   ► that we'd encourage is people who have been adopting async and await and things like that.

00:35:01 ◼   ► They will find, um, that turning on strict concurrency mode is a lot smoother for them,

00:35:05 ◼   ► but we've also in the latest compiler, um, added a lot more affordances, um, for example,

00:35:11 ◼   ► around not having to make your type sendable, but also be able to pass them through, uh, between

00:35:15 ◼   ► isolation domains. Um, one of the, one, one of the challenges with writing the latest talk is that

00:35:21 ◼   ► actually, um, I had these great examples, um, of problems that I was going to talk about and then

00:35:26 ◼   ► we fixed the compiler. So they weren't a problem anymore. It happened like three times. It's a

00:35:30 ◼   ► good problem to have. It's a very good problem. I mean, that brings me to the next topic. Like, uh,

00:35:34 ◼   ► for both of you, what is it like developing Swift in the open? Because like I'm, I'm watching all

00:35:38 ◼   ► year on Swift evolution. I see the features coming in Swift six is part of the reason I kind of backed

00:35:42 ◼   ► off my recent attempt and like they're fixing a bunch of stuff and so if six and you see them go

00:35:46 ◼   ► by, you see the proposals here, we're doing this thing, they're fixing the problems in your talk.

00:35:49 ◼   ► And I see it happening all throughout the year. That's very different than most other people here

00:35:53 ◼   ► at Apple. We, I mean, maybe some people sit down for WRC and they're shocked by Swift six, but if

00:35:57 ◼   ► you're, if you're following the forums and watching the proposals, it's developed in the open, it's

00:36:02 ◼   ► open source. Uh, the process of deciding what goes into it is open. There's no mystery involved.

00:36:08 ◼   ► What does that like for you in a company where that is absolutely not true of all the other teams

00:36:12 ◼   ► that you're working with except for maybe WebKit for WebKit, but also increasingly we're seeing

00:36:17 ◼   ► more of this style of operating. Um, foundation now is, is, is operating in similar fashion. So,

00:36:25 ◼   ► uh, and, and that has actually been key to the next thing that we've, uh, announced this year,

00:36:30 ◼   ► which is that we now have this single unified foundation code base, um, across platforms.

00:36:35 ◼   ► So the same foundation that you're running, um, on your phone and on your Mac, um, is the foundation

00:36:40 ◼   ► code that you will be running if you were to stand up a server running on Linux. Um, and so they've

00:36:46 ◼   ► been running, uh, language proposals, uh, sorry, language proposals, framework proposals, um, to,

00:36:53 ◼   ► uh, to introduce new features, um, such as, uh, I think, uh, predicate, uh, which is a foundation

00:36:59 ◼   ► type recently acquired support for regexes. And that proposal was discussed in the open. Uh, and

00:37:04 ◼   ► then the other example, uh, I heard your, um, podcast last week where you're wondering,

00:37:10 ◼   ► speculating about whether there was going to be a new testing framework.

00:37:13 ◼   ► That's because I couldn't remember the name of Swift testing. That's the one I had seen. Yes.

00:37:16 ◼   ► And yeah, so Swift testing was developed in the open. Um, it's, uh, it, it, we had some really

00:37:22 ◼   ► great, uh, community feedback from that. Um, and, uh, so that's another place where we're, we're,

00:37:28 ◼   ► we're doing, uh, that kind of, um, open dialogue with the community about, uh, sort of the next

00:37:32 ◼   ► layer up of, of, of Swift framework features. Is there any like, uh, can use it as an example

00:37:38 ◼   ► to the other groups? Like, look, we had, you have, we have a public issue tracker and people have

00:37:42 ◼   ► problems that we could discuss them in the open and look how much more efficient it is to go back

00:37:46 ◼   ► and forth on GitHub issues and discuss proposals. And these other groups are like sending carrier

00:37:51 ◼   ► pigeons across the country to through seven different intermediary parties with this game

00:37:55 ◼   ► of telephone to find one crashing bug. Like, do you ever like pitch the other groups and say,

00:37:59 ◼   ► Hey, I mean, I obviously worked on foundation or, you know, you could, this could be you,

00:38:03 ◼   ► you could be getting bug reports from people and communicating with them in an efficient manner and

00:38:07 ◼   ► and fixing them. Yeah. We get a huge amount of benefit from the Swift community. I think,

00:38:12 ◼   ► uh, when we bring ideas to them, uh, for new language features, um, we, we get this real

00:38:18 ◼   ► time feedback, uh, where they, the people on the forums, they spot issues with what we're proposing

00:38:23 ◼   ► that, uh, that we had not thought about. Um, and we, we iterate, uh, with them on that and we get

00:38:30 ◼   ► a huge amount of value from getting that real time feedback from people. And so I would, I would, uh,

00:38:35 ◼   ► I would say that's certainly been a valuable process for us. Plus you get to argue about

00:38:38 ◼   ► keywords, the true purpose of every language. We do. We we've fallen into this mode now where we,

00:38:45 ◼   ► we, um, this is something we've, we we've, uh, evolved as a process in the language steering

00:38:50 ◼   ► group that, uh, that Holly and I sit on, which is, uh, we're now in this mode where we will agree a,

00:38:56 ◼   ► uh, a proposal in principle where we talk about the fundamentals of the language proposal and how

00:39:00 ◼   ► it's going to work. Um, and then what we say is we've agreed that in principle, and now there's

00:39:05 ◼   ► like a free swim where everybody gets to specifically focus on the name we're going to use

00:39:09 ◼   ► for the keyword. Um, and that has actually helped the process a lot because the, um,

00:39:14 ◼   ► the bike shedding is a shiny thing that people immediately move towards. And so

00:39:19 ◼   ► if we say like, let's park the park, the name discussion for now, let's talk about the fundamental

00:39:24 ◼   ► feature. Then when we've agreed the fundamental feature and we accept it in principle, then we

00:39:27 ◼   ► can have like a discussion about what we're actually going to call it. And I mean, I know

00:39:31 ◼   ► that's, that's a source of contention and it's a silly argument with people, but it really does

00:39:35 ◼   ► make a big difference in language. So I like some people look at that like switch evolution or other

00:39:39 ◼   ► language lists and they're like, it just seems like a bunch of people arguing over like whether

00:39:42 ◼   ► copyable should have a tilde in front of her. It should be a new keyword or like, like, but that's

00:39:47 ◼   ► so important because those decisions you make, people live with those for decades. So you should

00:39:52 ◼   ► like spend a month arguing about it, make it because I've seen, I've seen it change. And

00:39:55 ◼   ► so the illusion like the original proposal will have this thing or whatever, and you'll end up

00:39:59 ◼   ► with a different thing and it's better. You're making it better by arguing about it. I guess

00:40:02 ◼   ► people just don't have a tolerance for it. They think, oh, that's not important. I don't care

00:40:04 ◼   ► what the word is called, but it makes such a big difference to the language. And you know, anytime

00:40:08 ◼   ► you make like a slightly wrong choice, like I remember, uh, so I was talking to, I don't know,

00:40:11 ◼   ► it was Dennis Ritchie or one of the old Unix guys or whatever said, do you have any regrets about

00:40:15 ◼   ► your career? And he said, I wish I'd put E and E on the create system call, you know, C-R-E-A-T.

00:40:19 ◼   ► Wow. How long has he been living with that? Like, and like, I just, I wanted to save that character

00:40:23 ◼   ► and now it's create for just for the rest of it. We're all, it's on Mac OS. It's on every Apple

00:40:27 ◼   ► platform right now, somewhere in the source code, there's a call to create with no E on it because

00:40:31 ◼   ► this guy made a bad decision in the seventies. And so you don't want that to be you. So yeah,

00:40:35 ◼   ► spend the time arguing about it. And I think that what you said, like doing the,

00:40:38 ◼   ► figuring out what you're going to do in the arguing about the keywords is a nice separation.

00:40:41 ◼   ► So you can make forward progress, but I'm here to endorse arguing about keywords.

00:40:45 ◼   ► It's also really valuable because there was a recent proposal called sending parameter and

00:40:51 ◼   ► result modifiers. And we, we did the same thing there where we, you know, had the concept from

00:40:56 ◼   ► the proposal. We accepted it in principle. And then we had a revision review to focus on the

00:41:00 ◼   ► name of the keyword, which was originally called transferring. Now it's called sending.

00:41:04 ◼   ► But the revision review thread is really interesting because a lot of people are coming in

00:41:08 ◼   ► and as part of justifying why they think this keyword should be called something specific,

00:41:13 ◼   ► they're reasoning through how they're thinking about the feature and how they would explain it

00:41:17 ◼   ► to other people. And at points where they maybe got something slightly wrong, someone else would

00:41:22 ◼   ► come in and say, Oh, I think this actually works this way. And I think this keyword's a little bit

00:41:26 ◼   ► misleading. And so that review is really cool because it wasn't, it didn't feel like a really

00:41:32 ◼   ► heated contentious debate. It felt like a healthy debate of people trying to come in and explain a

00:41:37 ◼   ► concept and then listening to other people explain how they thought about it. And that's also

00:41:42 ◼   ► valuable for us in figuring out how to actually explain the feature to Swift programmers, because

00:41:48 ◼   ► what the formal specification is in the proposal is not, you know, the level of detail that you

00:41:55 ◼   ► actually need to understand in order to use the feature. So yeah, those, those named bike shedding

00:42:00 ◼   ► threads are valuable for, for a bunch of different reasons. That's part of the reason doing it in

00:42:03 ◼   ► public, I feel like it's so beneficial because the people who are working on the proposal,

00:42:07 ◼   ► know it at such an intimate level. And then you throw it in a bunch of people who have no idea

00:42:10 ◼   ► what you're talking about and they will tell you, this is confusing to me. Like whether you're using

00:42:14 ◼   ► a term of art, it's meaningful to compiler people, or you've just all internalized as a group, what

00:42:18 ◼   ► this means, because you've been debating it for a month or whatever. And the word doesn't, doesn't

00:42:22 ◼   ► ring make in their mind, make them think of what it actually is. And so changing the word will

00:42:27 ◼   ► make it more learnable and more memorable. And, and again, the people who don't like bike shedding

00:42:30 ◼   ► will say, well, yeah, it's a weird word, but you learn it and then it just becomes internalized.

00:42:35 ◼   ► That's what happens to everybody, but that's, that doesn't make the language approachable.

00:42:37 ◼   ► If you pick a good word, it will, if the word means what you want it to mean,

00:42:41 ◼   ► it will help people learn the feature faster. I definitely find that because, you know, again,

00:42:45 ◼   ► some, some Swift features, I read the proposal and I don't understand it until you change the

00:42:49 ◼   ► keyword. And then I'm like, I'll read the same proposal. I'm like, Oh, now I get it because the

00:42:53 ◼   ► word you've chosen is different. And now I understand what you're getting it. Even non

00:42:56 ◼   ► copyable types was like that. It's like, didn't understand what you were trying to do until it

00:43:00 ◼   ► went around a few times. I'm like, okay, start like the sending and whatever. And I think you

00:43:04 ◼   ► picked that because of the, the, was it part of the synergy with sendable and everything?

00:43:08 ◼   ► The connection with concurrency. Yeah. Previously it didn't sound like it had anything to do with

00:43:12 ◼   ► concurrency. And so, so riffing off of sendable in a slightly different form so that it's not like,

00:43:17 ◼   ► if I'm talking about sendable versus sendable, someone did actually suggest calling it like

00:43:20 ◼   ► lowercase S sendable, but that's really difficult to talk about. But sending is close enough that

00:43:25 ◼   ► you're, it's very clear. You're talking about sending a value over an isolation boundary

00:43:28 ◼   ► because that's the term that Swift uses for that concept. So you have this immediate connection

00:43:31 ◼   ► to concurrency and then you can dig in deeper to how it works. Just don't, don't let the math

00:43:35 ◼   ► people use the language. Well, it's funny just to kind of reiterate what John said. You know,

00:43:39 ◼   ► when I still had a real job and I was working with other switch developers, it was hilarious.

00:43:43 ◼   ► The younger ones when our code base was some objective C was largely Swift, but you would bring

00:43:49 ◼   ► a young, typically a younger person who has grown up on more, you know, JavaScript languages. And,

00:43:56 ◼   ► and I think Swift is like that. And I don't mean that in a bad way. I mean that in a good way,

00:44:00 ◼   ► it's much more approachable. And then we would, they would look at a file of objective C and they

00:44:05 ◼   ► would just recoil because it just looks so different. Like even though they're, I like

00:44:10 ◼   ► objective C just fine. I'm not a super fan, but I like it just fine, but it's so much less

00:44:14 ◼   ► approachable. I think in so many ways, because it's so different. And I think those silly

00:44:18 ◼   ► arguments about a till day, one of you said a minute ago, like a till day or not, and what

00:44:21 ◼   ► keyword to use, they, they really dramatically in aggregate can change the whole kind of vibe of a

00:44:27 ◼   ► language and Swift's vibe. I think Marco had said earlier, or maybe somebody has said, you know,

00:44:33 ◼   ► there was a window, a time where it was getting a little architecture astronautty, I feel like,

00:44:37 ◼   ► but I feel like that's really been brought around in a good way. And I feel like we're,

00:44:41 ◼   ► we're heading on a good path. And those arguments, while I was one of those people that was like,

00:44:46 ◼   ► Oh my God, why do I care? But then you just like John said, you think about it for a minute. You're

00:44:49 ◼   ► like, Oh no, this is, this is where, and this is what you two just said, this is worth arguing

00:44:52 ◼   ► about. And I think it's important. Architecture astronauts are saving your butt. Okay.

00:44:57 ◼   ► You do a good, you're doing a good enough job of architecture astronaut and you're like, Oh,

00:45:00 ◼   ► they all went away. No, they didn't. They just did. They just did their job.

00:45:03 ◼   ► No, that's fair. That's fair. That's fair. Correct.

00:45:05 ◼   ► Yeah. I mean, the goal is very much, we have to plot this path, right. Between helping people

00:45:10 ◼   ► make code correct. And also helping make people easily able to bring forth what's what's on their

00:45:16 ◼   ► mind and make it like a low ceremony language where they don't have to put that many keywords.

00:45:21 ◼   ► And sometimes those two things can be intention. And that's something that the community really

00:45:26 ◼   ► helps us work through. Right. Like, so, um, I think even with concurrency, right, the, the,

00:45:32 ◼   ► the strict checking mode, the goal there is to have the compiler help you work through exactly

00:45:37 ◼   ► what you're trying to express. Um, and so, um, sometimes we do have to, to, to resolve that

00:45:43 ◼   ► tension. And that's really the game of language design is making sure that we keep that vision

00:45:47 ◼   ► of having Swift be as low ceremony as possible, but not any lower than that. Right. Because if

00:45:52 ◼   ► you have like no ceremony, then you don't know what's going on. And right now you're in like

00:45:57 ◼   ► an untyped language where you, it's really difficult to, to understand exactly what the

00:46:01 ◼   ► code is doing. If you have too much ceremony, then you get, you know, a language more like Java,

00:46:06 ◼   ► where you have to like ride a, uh, multiple different things to, to achieve the same result

00:46:10 ◼   ► that in Swift would just be like a couple of, uh, a couple of words. So yeah, it's, it's plotting

00:46:16 ◼   ► that path. And that's actually something that, that we, we think Swift hits the spot of,

00:46:20 ◼   ► which is why we think it will be such a great language to expand beyond, um, just its existing,

00:46:25 ◼   ► um, app development ecosystem and expand into other places where people want like the performance of a,

00:46:32 ◼   ► of a head of time compiled language that doesn't have garbage collection. Um, whilst also giving

00:46:38 ◼   ► you the ability to have like a joyful experience writing code where you don't have to write that

00:46:41 ◼   ► much code and you don't have to fit too much stuff in your head at once. Still hanging on to that

00:46:44 ◼   ► dream Swift being the, uh, the language that spans from the, uh, the, the lowest level of the

00:46:48 ◼   ► operating system up to a scripting. And there's, there's a lot of programmers who are the potential

00:46:52 ◼   ► audience for Swift, but obviously a lot of the programmers who are your target audience are

00:46:57 ◼   ► Apple employees. How do you work with the other teams at Apple when it comes to language features?

00:47:02 ◼   ► How does that work? So did you just give example, like result builders, uh, for the Swift UI thing,

00:47:07 ◼   ► non-copyable types, objective C interop, like, do you come to them and say, Hey, we think I have an

00:47:13 ◼   ► idea. Did they come to you? Like how, what is the interaction with the rest of Apple for language

00:47:16 ◼   ► features, the language readers that will obviously they will benefit everybody when they get out there

00:47:20 ◼   ► in the world. But sometimes you look at them, you're like, Hey, that was language feature that

00:47:22 ◼   ► was made specifically for teams at Apple. So they could adopt Swift fast or whatever.

00:47:27 ◼   ► I mean, I think the way I would think about it is that no feature is ever good unless you use it.

00:47:33 ◼   ► So when we're developing a feature, we really need to use, we really need to do that development

00:47:39 ◼   ► with somebody who is directly using that feature. And ideally you do that development in real time.

00:47:46 ◼   ► And so, um, when we're working with, um, a team like the Swift UI team, um, we really want to

00:47:53 ◼   ► know that something like result builders is really going to hit the spot of them being able to create

00:47:57 ◼   ► that, that really expressive API and develop that feature with them and have them use it and give us

00:48:04 ◼   ► feedback. Are you bringing result builders to them or are they bringing the idea of the Swift UI to

00:48:08 ◼   ► you and saying, we need, we need a generic system to do this? Like how is it? I don't think Swift UI

00:48:13 ◼   ► in particular is not, or any, or any, so another example would be embedded Swift. So, um, obviously

00:48:18 ◼   ► we, we're, we've got a lot of material this week. Um, and we've been putting it up actually prior

00:48:22 ◼   ► to this week, um, encouraging people to check out embedded Swift and use it for, um, you know,

00:48:27 ◼   ► developing for the raspberry PI Pico or the play date or something like that. But we also developed

00:48:32 ◼   ► it in conjunction with some of our, uh, developers who are working on things like the secure enclave.

00:48:38 ◼   ► And we've talked about, that's actually one of the, the, the places where we've adopted it this year.

00:48:42 ◼   ► Um, and so we directly work with them and they inform, um, you know, our thinking about how to

00:48:49 ◼   ► target that language mode. And it really ends up being a better product. I think if we developed

00:48:54 ◼   ► the language ahead of time and then said, here it is, we knew you needed to do some firmware

00:48:58 ◼   ► development. Here's a language that does it. We would not get as good a result. And my, another,

00:49:02 ◼   ► another example of soft UI is like the old, the old, uh, limitation for the parameter things.

00:49:07 ◼   ► You get one through 10 or whatever, and it wasn't parameter packs or whatever the thing that goes

00:49:10 ◼   ► around that. It was that an example of like, okay, well you obviously didn't have the language

00:49:14 ◼   ► teacher. They rolled out Swift UI anyway, and there was this kind of, you know, semi not well

00:49:18 ◼   ► known limitation or whatever. And why was the limitation? There was a language limitation. Then

00:49:21 ◼   ► you could look at that and say, all right, well, our language is failing the team here. How can we

00:49:27 ◼   ► solve that? But not just by like hard coding, I think for a few, I, but adding a language feature

00:49:31 ◼   ► that now is, you know, beneficial to anybody who wants to use it. But as a side effect,

00:49:36 ◼   ► that limitation is Swift UI is gone. Yeah. So parameter packs specifically were a generics

00:49:41 ◼   ► feature that I think we always knew we, we wanted to have because there's such a wide variety of use

00:49:47 ◼   ► cases for them. And, um, Swift UI view builder is not the only API that adopted parameter packs.

00:49:52 ◼   ► Last year. You also see it in foundations, predicate API. Um, you see it in weather kit APIs

00:49:58 ◼   ► and because there's a lot of APIs that are structured like that, where you have a variable

00:50:01 ◼   ► number of things that you pass in and then you get the same variable number of things as your output

00:50:05 ◼   ► there. Um, but I, I help a lot of people try to express something in Swift, you know, every day

00:50:12 ◼   ► across a wide variety of framework teams, people writing apps, people on the forums. Um, and one

00:50:17 ◼   ► really important job of my team, uh, the, the language team is to take, see all of these

00:50:22 ◼   ► different use cases that people have. Um, and first and foremost, help them use the language

00:50:27 ◼   ► as it is today. And a lot of cases, people are just trying to use some feature that already exists

00:50:31 ◼   ► and they need some help figuring out how to exactly make it work for their specific use case.

00:50:36 ◼   ► And in cases where there is an expressivity limitation in the language, um, we take all of

00:50:42 ◼   ► these different use cases, again, from a variety of different sources. Um, we use the forums as a

00:50:47 ◼   ► big source of use cases for different things as well. Um, macros are a really great example of

00:50:52 ◼   ► this. Um, we, there were a variety of different use cases, um, for frameworks at Apple, Swift data

00:50:58 ◼   ► adopted macros. Um, the new observation, uh, library from last year as part of the Swift

00:51:03 ◼   ► standard library uses macros, but there were also a ton of use cases spinning up on the forums about

00:51:07 ◼   ► people who were wanting to do, to do really similar things in their code. And something

00:51:11 ◼   ► that was awesome during the review process of macros and Swift evolution was, um, people were

00:51:18 ◼   ► trying it out and putting up example macro packages, um, on GitHub. And, uh, that also

00:51:24 ◼   ► was a really great example of people actually trying out the feature and seeing how it worked

00:51:28 ◼   ► for them, um, at the same time that it was being developed and that turned into real feedback that

00:51:33 ◼   ► was incorporated into the design. Um, so yeah, usually the way that these things work out,

00:51:38 ◼   ► unless there's some big overarching goal, like, um, data race safety, that, that was a goal that

00:51:42 ◼   ► was driven by us. Um, but a lot of times it's that we're helping so many different people use

00:51:47 ◼   ► the language, um, in a variety of different ways, and we can, um, you know, generalize

00:51:53 ◼   ► these expressivity limitations into a single language feature that works for everybody. Um,

00:51:58 ◼   ► it's a really interesting process.

00:52:01 ◼   ► parameter packs is actually a, uh, I think an example where we really feel like we're

00:52:06 ◼   ► successfully doing what we try to do, which is have this progressive disclosure where we have

00:52:10 ◼   ► these really advanced language features that ultimately are able to produce APIs, help people

00:52:17 ◼   ► produce APIs that you would not know you're using these advanced features when you use them day to

00:52:22 ◼   ► day. You do not know when you go create a view with 11 things in it that actually that is

00:52:26 ◼   ► only possible because of parameter packs. You don't, you don't know that when you're, when you've

00:52:29 ◼   ► got this really nice API where you tell the weather API to give you like temperature and wind speed,

00:52:34 ◼   ► it's actually giving you two strongly typed values that then instead of giving you like two untyped

00:52:39 ◼   ► values, like in any type value that you used to have before you immediately get these two strongly

00:52:44 ◼   ► typed values where you get like code completion on exactly the, the, the, the types that you have,

00:52:48 ◼   ► that, that, uh, that make it so much easier to use. Um, macros is another example where like

00:52:53 ◼   ► the creation of macros was general enough that people were able to create these great new APIs

00:52:59 ◼   ► that you do not have to think about when you're using them. So Swift testing is another one. I

00:53:03 ◼   ► know you folks were ragging on the Flint design, uh, of other testing frameworks. And one of the

00:53:09 ◼   ► beautiful things about Swift testing is that you write just regular expressions. I'm sorry.

00:53:14 ◼   ► I shouldn't say that was the wrong term. You write ordinary expressions, ordinary Swift expressions,

00:53:21 ◼   ► like a is not equal to nil or something like that. Um, you put them inside a pound expect and then,

00:53:28 ◼   ► um, the pound expect macro will do some magic stuff under the hood to do reflection actually

00:53:32 ◼   ► exactly similar to what you were talking about, where it breaks down the object and looks at all

00:53:35 ◼   ► the different properties. We don't have different quiet. That's a great idea to maybe bring to the

00:53:38 ◼   ► Swift forums and talk about it. You just look at any other testing framework. I'm pretty sure they

00:53:42 ◼   ► know what they know. They know it exists. Fair enough. That's the thing with testing frameworks.

00:53:45 ◼   ► There's so many of them. There's so much prior art and XC test was a little bit crusty, but like,

00:53:49 ◼   ► there's, you're spoiled for choice. You just look at all of the popular languages and all the

00:53:53 ◼   ► testing frameworks and you've chosen this time, not to go with a bunch of words with dots between

00:53:56 ◼   ► them, but you know, some people like that. So I predict that Swift testing, uh, is, is it looks

00:54:01 ◼   ► like a great advancement over what came before, but I feel like testing frameworks are difficult

00:54:05 ◼   ► to get right on the second or third try. So going beyond XC test is great. You know, I, I, we

00:54:12 ◼   ► actually had planned to talk to the both of you about more about Swift testing, but in, in

00:54:15 ◼   ► interest of time, I wanted to give, or we wanted to give you guys a couple of, uh, the floor to

00:54:20 ◼   ► answer a couple of, uh, softball questions. Uh, first of all, I'm going to start a little bit

00:54:25 ◼   ► negative and then we're going to end with a positive. Is there any, I actually have a

00:54:31 ◼   ► statement. No, um, do you, is there, is there any common misunderstanding in the community that

00:54:38 ◼   ► maybe grinds your gears or you just feel bad? Like I'm trying to make this not so negative. Like you

00:54:43 ◼   ► just feel bad that people just haven't grokked that, Oh, you know, all of us, myself may be

00:54:47 ◼   ► included, think a, but it's actually Z, you know, or whatever the case may be. And maybe there isn't

00:54:52 ◼   ► anything, but if you had, let's say, you know, a couple of minutes to correct some common

00:54:57 ◼   ► misunderstanding, is there anything that jumps to mind about Swift? Not just the,

00:55:01 ◼   ► yeah, there, there is one immediate one that comes to mind. Um, people in Swift love protocols.

00:55:06 ◼   ► Protocols are great. I love protocols too. Um, but a lot of people when they're starting to write,

00:55:11 ◼   ► you know, an app, um, they start by adding a protocol into their code and then they end up,

00:55:17 ◼   ► um, using a lot more abstraction than they really needed to in their code. Like they

00:55:22 ◼   ► ended up using any types or if you're familiar with the formal term existential types, um,

00:55:26 ◼   ► which we had tried to steer people away from because those are a really complicated feature

00:55:31 ◼   ► and understanding why they have some of the behaviors they have, um, is, is really, really

00:55:36 ◼   ► nuanced and hard for a lot of people to grasp. And in a lot of cases you don't need them. Um, so I

00:55:41 ◼   ► would tell people to start with a concrete type, start with a struct specifically until you, um,

00:55:46 ◼   ► need more abstraction or you need, um, reference semantics and then sort of evolve from there. Um,

00:55:51 ◼   ► the same thing is true of, um, global, I've seen so many people write static variables that never

00:55:57 ◼   ► change throughout their code base. Um, so I would tell people to start with the lead and that's

00:56:01 ◼   ► really helpful for, um, data race safety as well. Yeah. I blame a, what is it? Uh, you maybe, you

00:56:06 ◼   ► know, a protocol oriented programming. Remember that I was thinking the same thing. A lot of

00:56:09 ◼   ► people went to that session. I like protocols. They're the future. I'm starting every app with

00:56:12 ◼   ► protocols. It's worth rewatching that talk. Like what the talk said was, if you're thinking about

00:56:17 ◼   ► creating a sub typing relationship instead of a class hierarchy, start with the protocol.

00:56:22 ◼   ► Unfortunately, what people heard was start with the, it's right in the title. You just,

00:56:27 ◼   ► they read the title and they're like, great, I'm on board. Right. And so it gets to that point where

00:56:32 ◼   ► like, it's kind of like the black box. Why don't they make the entire plane out of protocols? Right.

00:56:35 ◼   ► That's not what you want. You want to start from, uh, from structs, like Holly said,

00:56:40 ◼   ► and then generalize your problem when you find you need to generalize it. That's actually,

00:56:44 ◼   ► they generalize it from the start. Yep. No, that's really good advice. And then, uh, finally,

00:56:48 ◼   ► cause we really are running low on time. Uh, what are you proud of lately? Like, I mean, obviously,

00:56:52 ◼   ► and I mean, there's obvious answers like Swift concurrency in, in the strict concurrency.

00:56:57 ◼   ► It's an incredible land and you should be proud of that. But is there maybe something that,

00:57:01 ◼   ► that, you know, your pet feature or project or what have you, that maybe not a lot of people

00:57:06 ◼   ► seem like embedded Swift is a great example that, I mean, I've seen a lot of this on the WWDC session

00:57:10 ◼   ► titles anyway, but is there something maybe a little more esoteric or, or just your pet thing

00:57:15 ◼   ► that you're really, really into that you're proud of? I don't know if it's esoteric,

00:57:18 ◼   ► but I think we're pretty proud of the progress we've made around cross platform support.

00:57:21 ◼   ► That's especially something that we've been pushing this year. Um, we have, uh,

00:57:25 ◼   ► support for more distros this year. Um, we have now Debbie and, and fedora. Um, we've, uh, been

00:57:31 ◼   ► working with, um, uh, the community on creating this really great plugin for vs code that allows

00:57:37 ◼   ► you to, to use vs code. If that's what you're into. Um, personally I'm sticking with X code,

00:57:41 ◼   ► but like, and I know a lot of people have very personal preferences. Um, we also have some

00:57:45 ◼   ► articles up on how to, to integrate a code completion into a, uh, uh, near VIM and Emacs

00:57:51 ◼   ► if that's your jam as well. So, um, I think we've made really some really great progress in, in,

00:57:56 ◼   ► in that area. And, uh, we've seen, uh, both internally and in the outside community,

00:58:01 ◼   ► a lot of more, uh, rapid adoption of Swift on, on Linux environments, um, and on the server

00:58:07 ◼   ► generally. I think, um, if you saw, um, some discussion in the keynote to the fact that we're

00:58:12 ◼   ► now running Swift on the server to do some of the new Apple intelligence features. Um, and that's

00:58:16 ◼   ► all built on this foundation that we've been working on for years with projects like the Swift

00:58:20 ◼   ► Neo, uh, framework and things like that, that have always given us this ability to, to, to stand up

00:58:26 ◼   ► servers, um, that have this really, uh, great ability to, again, have this high level language

00:58:33 ◼   ► that we feel is really enjoyable to write, but that managed to get you in the case of the server,

00:58:37 ◼   ► really low memory footprints, um, which can be a big challenge when it comes to, um, to, to large

00:58:43 ◼   ► server, large server farms, especially. Um, and that's, that's been a really big win for us that

00:58:49 ◼   ► we're pretty proud of. World domination is still on the table. Still on the table. How about you,

00:58:52 ◼   ► Holly? Um, my team's focus this year was, um, you know, data race safety and Swift 6. I'm personally

00:58:59 ◼   ► really proud of my team because a lot of the team was new to the, um, data race safety model and the

00:59:04 ◼   ► concurrency model in general. Um, you know, at the beginning of this year, um, originally it was

00:59:11 ◼   ► built by a smaller group of engineers and then more people got involved in concurrency. So, um,

00:59:16 ◼   ► yeah, I'm, I'm really proud of the work that the team has put in in general into this release. And,

00:59:22 ◼   ► um, I'm also really excited by how the community has started to adopt these features and surface

00:59:29 ◼   ► feedback to us and talk about what's difficult, talk about what error messages are confusing and

00:59:34 ◼   ► sort of seeing the community, um, really embrace this new model of programming and come to a shared

00:59:41 ◼   ► understanding and, um, improve both the compiler and the documentation and the language. Um,

00:59:47 ◼   ► I'm really excited to see where this goes from here. That's awesome. Ben Cohen, thank you so

00:59:52 ◼   ► much for joining us. I really appreciate it. Thank you very much. Holly Borla. Thank you so very,

00:59:56 ◼   ► very much to both of you guys. We really, really appreciate it. Thank you so much for having us

01:00:00 ◼   ► and thank you to Apple for hosting. And with that, I think we're good. See you next week.

01:00:06 ◼   ► (beep)