Edge of Concurrency with Matt Massicotte - podcast episode cover

Edge of Concurrency with Matt Massicotte

Aug 04, 202332 minEp. 158
--:--
--:--
Listen in podcast apps:

Episode description

Matt Massicotte from Chime talks about the challenges he faced migrating the Async/Await and some misconceptions folks might have with asynchronous programming.

Guest

Related Links 

Related Links 

Social Media

Email
[email protected]
GitHub - @brightdigit

Twitter
BrightDigit - @brightdigit

Leo - @leogdion

LinkedIn
BrightDigit

Leo

Instagram - @brightdigit
Patreon - empowerappshow

Credits

Music from https://filmmusic.io
"Blippy Trance" by Kevin MacLeod (https://incompetech.com)
License: CC BY (http://creativecommons.org/licenses/by/4.0/)

  • (00:00) - What's (Not) New with ExtensionKit
  • (03:06) - Migrating to Async/Await
  • (10:59) - Dealing with Older APIs
  • (12:46) - On Swift 6
  • (18:59) - Locks and Semaphore
  • (24:48) - Swift Proposals
  • (27:31) - WWDC 2023
Thanks to our monthly supporters
  • Maurizio Bracchitta
  • Edward Sanchez
  • Satoshi Mitsumori
  • Steven Lipton
★ Support this podcast on Patreon ★

Transcript

Leo Dion (host): Welcome to another episode of Empower Apps. I'm your host, Leo Dion. Today, I'm joined by Matt Massacott again. Matt, thank you so much for coming back on the show. Matt Massicote (guest): I'm happy to be here. Thanks for having me. Leo Dion (host): Before we get into your upcoming presentation at Swift Toronto. Go ahead and I'll let you introduce yourself and chime. Matt Massicote (guest): Sure. Well, my name is Matt. I'm a longtime macOS developer.

I've done a little bit of iOS, but not that much. I put some time in at Apple, working on iOS actually and then ended up working independently and so I'm like a part time independent developer right now. And one of the main projects I work on is called Chime, which is a like lightweight minimalistic editor for the Mac. Leo Dion (host): And we had you on, was it last year or a year and a half ago to talk about extension kit? Matt Massicote (guest): yeah, yeah, it was right about a year ago.

And it's funny. Leo Dion (host): go ahead. Matt Massicote (guest): It's funny because I don't remember where I was in my extension kit journey when we talked. But all the stuff that's come up for my work on concurrency started there. Leo Dion (host): Okay before we get into that, I do want to ask did anything happen with Extension Kit since DubDub, and as far as Extension Kit is concerned, like, how's that going, outside of what we'll talk about today?

Matt Massicote (guest): I would, I would love to sit down with somebody who works on extension kit at Apple and just hear the story about what is going on there because they just to remind people. So it was introduced. Last year with absolutely no mention at all during Leo Dion (host): talks. Yeah, Matt Massicote (guest): Yeah, no, nothing, which is really unusual. Additionally, it's a weird thing to add to Mac OS, right?

Because almost all of it, almost all the features that it provides were technically possible before they were extension kit makes it easier, but loading code as plugins is all things that you could do before. So the end parts of extension kits. Are, and to this day, still exposed on iOS. So it was a weird, it was a weird thing. And it really felt to me it was supposed to launch for iOS. Got pulled at the last minute, that's why we saw no video about it.

And they just kinda let it sit, until this year. And then so this coming up year, I was convinced, 100% convinced, that it was gonna be released for iOS. And what's weird is, more of it was added, more API was added to iOS. But still not enough to actually use it. And there was also no videos about it. Leo Dion (host): How about Mac OS? Anything different there? Matt Massicote (guest): No, it's basically the same. Leo Dion (host): Okay. Interesting.

Matt Massicote (guest): Yeah. So something funny is going on. Leo Dion (host): Yeah, yeah, yeah. Is it only available on Mac OS? So, no vision, no watch, no TV. Matt Massicote (guest): vision OS is the same. No watch, but vision OS and iOS and, and well, iPad, it's the same thing where there's portions of it are available on iOS, but not enough to actually use it. Leo Dion (host): Okay. Matt Massicote (guest): Just bizarre. Leo Dion (host): we'll put links to our previous episode.

I'm definitely interested in jumping into it once I get farther with Bushel. But, yeah, it's, it's interesting. So it sounds like... Your work in extension kit, you found out a few little quirks with async await specifically you want to give just the big picture of what kind of issues you've run into. Matt Massicote (guest): Yes, absolutely. Well, so it started with my work on extension kit. Part of the idea here is you build an API that other developers are going to use.

And it's this public API that you publish as part of your extension kit, SDK, however you're going to package it up. And so I thought, well, if I'm going to do this, I might as well be as forward looking as possible. At the time, I hadn't looked at concurrency at all, but I thought this is a great opportunity. I'm going to dive in here and I'm going to see if I can make it work. And at the beginning, that seemed like a wonderful idea. It was, it's felt easy.

It felt like you're just getting rid of completion of completion handlers and replacing them with the async keyword. Like it felt really nice. And I got pretty far with it. The integration with Chime is also probably uncharacteristically deep. I would imagine that most people that are going to be using extension kit, it's going to be a small feature that you're going to expose. But with QIIME, it just made a lot of sense.

So it's very deeply integrated into the application, used all over the place, everywhere. And so it impacted pretty much everything about how the app works. And that meant that concurrency started, it's a little bit viral. And so it started getting it working its way into more parts of the application.

And I think the first thing that really hit me when I started realizing, okay, I don't know if I know what I'm doing is I started seeing really terrible race conditions where I would have like these events happening ABC, but, but what would be happening in the extension would be, they would not be in that order. Leo Dion (host): Hmm. Okay.

Matt Massicote (guest): And at first I was like deeply confused by this, but after I started looking into it, I realized that it makes everything makes total sense. What was happening, what was going on here was I was just putting these unstructured tasks. To start running, to get, to get an async context.

And I think this is a thing a lot of people will do, is that apps fundamentally, they start with one thread, one main, one main, I mean actor, but one main thread, and eventually they're going to start running stuff, and they need some sort of async context to do that. And so in many cases, And if you look at, you'll see blog posts all over the place saying concurrency is easy. And if you don't have an async context, you just use a task and you're done.

And that is technically true, but tasks don't synchronize across each other. So you can make them synchronized. You can start task A and then wait inside of task B for task A to be done. That's totally allowed. That's the way you do it. Leo Dion (host): Mhm. Matt Massicote (guest): But if you don't establish these explicit dependencies across tasks, they run in any order. There's absolutely no dependency enforced by the system at all.

And so this is where I first started running into problems is because I was introducing concurrency in this fundamental part of my app, but they were not really connected inside of the app structure. So there's one call over here and then many, many, many, many, many layers and APIs distant from that place, there'd be another async call that I needed to make. And previously, those were completion handlers.

They would start, run a bunch of code, and then this one would start and they would always start one after another. And replacing those calls, those completion based calls with tasks meant that that ordering was no longer being enforced. And that's really the fundamental thing that I was running into, Leo Dion (host): That. Okay. I'm gonna, I'm gonna. Don't take this the wrong way, but that sounds like a feature, not a bug. Matt Massicote (guest): Being ordered.

Leo Dion (host): yeah, because yeah, that's where you're kind of like, for me, an async task would be something you just run whenever you want to, and it has no dependencies per se. But what it sounds like here is is you need to set up some sort of it sounds like a use case for an actor where you have one central lane where things are run and it can only be run on that lane. Is that correct? Matt Massicote (guest): actually, no, but that's a very, that, that makes sense what you're saying.

And you're right, it's not a bug, it's a, what this is, is an implication of changing from completion based systems to async systems. Leo Dion (host): right, right, Matt Massicote (guest): And so the implication, and it's like, took me a super long time to actually even understand, like, what is going on here. And the reason is that a completion based system has, you call it synchronously, and then it will do its work internally, it'll do its work asynchronously.

And an async based system cannot, it is impossible to do that with an async based system. The caller is the one who's responsible for coordinating these Leo Dion (host): right, right, right, Matt Massicote (guest): You might have some nice object that has a whole bunch of completion handler based blocks, and internally, it's got its own dispatch queue, and when you make a call, it synchronizes everything internally. And that is no longer possible to do.

That pattern is not possible to do with Swift concurrency. Leo Dion (host): right, right. So you're sa Matt Massicote (guest): not supported Leo Dion (host): so you were saying actors are not what you want. Can you explain that a little bit more?

Matt Massicote (guest): because you have to use the async keyword as soon as you use the as soon as you introduce a wait It's up to the caller that writes a wait to do the ordering actors cannot internalize that stuff and you might and at first you might Think oh, of course they could because you just put the queue inside of the actor and that's true You can put the queue inside of the actor, but you no longer have the ability to serialize Putting stuff in that queue. That's up to callers.

And so this is like this fundamental change. I think a lot of people are very used to, I certainly was, used to writing code this way, and you just can't do that anymore. When you're going into concurrent. Leo Dion (host): okay. So what did you end up doing to get around that? Matt Massicote (guest): Well, first I would say I swore a whole bunch, and then figured out what the problem was.

It took me a long time to even understand the problem, but once I got it, what I ended up doing was introducing a queue. Like, fundamentally, you need a queue. There are many problems, many, any, pretty much any time you have a stateful system, you have to be able to serialize these things. And so I had to introduce a queue.

But I had this problem because I had a whole bunch of legacy code and I could have like spawned task A. Up at the top, grabbed grabbed it in a variable and then passed it through all these callers to the spot where I called task B that would have worked. But it was just so awkward. And so it was just totally unwieldy to do that. So what I did was I introduced a global queue. So one queue for the entire application.

And I could submit, instead of just standalone tasks, I would make a, make a task, that task, and then put it into this global queue. Leo Dion (host): Okay. Matt Massicote (guest): And that was my, I suppose I would call that my my stopgap solution. That enabled me to remove all the race conditions. It's gross, but it was possible to do.

Leo Dion (host): What if, like, what other people, what, what if other people, what if you found other people are doing online for what you're particularly running into here? Matt Massicote (guest): I have not found anybody really talking about this exact kind of problem in this way. I think people have noticed the ordering problem of a standalone unstructured task is very well understood. And you said, it's not a bug, it's a feature. And you're right, that is how it's supposed to work.

But I think that when you start introducing concurrency, With stateful systems into existing applications. That's the only time these kinds of things are really going to come up. Leo Dion (host): yeah, and it's I think that's the key is like stateful right where it's like Oh, you need to know when something is ready and then run the task Matt Massicote (guest): right? Absolutely.

That's the critical component of, I think many people have been introducing concurrency into their apps, using things like the SwiftUI. task, and they're probably loading code, not loading code, loading data from some remote from stateful. Leo Dion (host): Right, right. Yeah. What I wanted to jump in and talk a little bit more about you mentioned some like older APIs that you're running into were any of those running into issues with async await?

Now I'll, I'll just preface by saying I've run into issues with like NS operation, like maintaining some old code that uses NS operation. And then we want to do async await. And it's like, Oh yeah, there's like all sorts of issues with older objective C APIs once you start doing async await, did you run into anything like that? Matt Massicote (guest): I'm very curious what your problem was, but first I'll say I totally did.

So, I think that the, my first realization along this journey was that I didn't really understand how to establish asynchronous contexts in a way that would let me do the things I was already doing. That was like one big realization. But then the second really important realization was All the warnings are turned off by default. And so what I was doing, was I was making an API that was inherently async, but I was, because there was no warnings, I didn't understand how to do that correctly.

Leo Dion (host): Okay. Matt Massicote (guest): And so once I started realizing, okay, in order to do this, I have to turn on these warnings, turned on these warnings I had built an API that was fundamentally incompatible. And then what does that even mean? And it could be what you're talking about is if you have an async function, it needs to be either accepting sendable stuff or it needs to be both accepting sendable stuff and returning sendable things or isolated to a global actor.

And you have no other alternative. That is it. Leo Dion (host): Right. Right. Mm hmm. Matt Massicote (guest): And so what's interesting. So two things I have noticed existing APIs. One is apple. I think many people on apple in apple internally did not realize this was the case. Leo Dion (host): Mm Matt Massicote (guest): And so apple has shipped a few APIs that don't pass these warnings, but they are explicitly async.

Leo Dion (host): Yeah. Matt Massicote (guest): like one example I'll give that I just happened to notice was it's in HealthKit. It was like a HealthKit, I can't remember if it's called Query, but it's called an async query. And it is specifically built to allow you to use concurrency both accepted and returned non sendable stuff. So whoever made this did not understand that that was, that was an impossible API to build.

Leo Dion (host): Yeah. And I think that's a big, like, that's a big Swift 6 thing is like, all that stuff has to be fixed by then. Matt Massicote (guest): Right. But now, so the health kit team had this problem, right? Because, because they ship this API, they, they must either make the HK health store, I think it's called. And they must make that sendable as well as the return value, or they were going to have to deprecate this API.

Cause if they couldn't make them sendable, this API can never be made to work. Well, I suppose Leo Dion (host): isn't there like an attribute where it can basically say, Oh yeah, it's sendable, don't worry about it, and you don't Matt Massicote (guest): has to actually be sendable, but yes, yes, Leo Dion (host): Okay. Okay. Matt Massicote (guest): You're right. I suppose the other, other alternative and one that I have used a lot is you just can't use this on anything other than a global actor.

Leo Dion (host): Yeah. Matt Massicote (guest): hammer that you can use that you can always put things onto your own global actors onto the main actor. And that is necessary in many cases Leo Dion (host): so we healthcare, were there any other APIs you ran into like any app kit stuff or anything like Matt Massicote (guest): well, extension kit. Leo Dion (host): Okay. Matt Massicote (guest): so, and widget kit. So the, so examples of these things are, these are APIs where.

It's probably supposed to be main actor isolated and by all accounts, by how you're understanding how the API is work, it really should be, but Apple has not done that annotation yet. Leo Dion (host): I want to say like, if you do any of the new stuff in, in Xcode 15 beta, everything is like automatically main actored for you. Oh, really? Matt Massicote (guest): Yeah. So both extension kit and widget kit are still not fixed. And so they're impossible to use without warnings.

Leo Dion (host): Okay. I know SwiftUI, I used to have to put everything in a main actor for UI changes for obvious reasons, but now, like, they automatically do that for you. So, Matt Massicote (guest): Yeah. You know, there's a really strange Swift UI in particular. There's a really strange behavior. I'm going to mix up which one it is off the top of my head, but there are, it's possible for property wrappers, which is used all over the place in Swift UI to implicitly impose actor isolation.

So this is the thing that trips up so many people cause they don't understand. They're like, if I remove an at state object, everything, if I, if I leave in the at state object, everything works. And if I remove it, all of a sudden I'm getting warnings about not being on the main actor, what's going on here. And the reason is that as of right now, property wrappers can change the actor ness of the type that uses them.

Leo Dion (host): Well, I'm wondering, too, like, you can put, you can say something as main actor on a protocol, and then if you're putting all sorts of semantic sugar, like, macros, if it's automatically putting that in there for you, too. Because I've been doing a lot more observation stuff, and less, like, the Matt Massicote (guest): that is possible also. But I can tell you that they're going to remove that behavior.

So the behavior of protocol of excuse me, of property wrappers, changing actor ness of types is Leo Dion (host): Okay. Okay. Matt Massicote (guest): because it just, it's confusing everybody. And so that's, you might need to start putting more at main actors on your types because of that. Leo Dion (host): Yeah. Yeah.

Yeah. Yeah. And that's, I've, so going back to what you were talking about, about like sendable and stuff, there's like, at least as far as an Xcode and in the Swift package, you can, you can turn those flags on and, Man, like, yeah, I've run into, so there's all sorts of actor stuff you have to add for Swift 6, there's every protocol now requires any keyword, like, it's crazy how much stuff and it's understandable why we haven't seen Swift 6 being ready yet after, after dub dub, so, yeah.

Matt Massicote (guest): know, I, so I think that, and I'm going to make this prediction in my talk, but I think that's probably going to be the theme. I think, I think that Swift 6 is going to be rough because I think there are Leo Dion (host): I think it's going to be the roughest since, whatever, SWF3 or SWF4, whenever we got ABI Stability. It's been a while since we've had any rough upgrades in SWF, so yeah, I agree. Matt Massicote (guest): going to be even rougher.

I think it's going to be the worst one yet. Yeah. And the reason because, and I'm just using my experience as an example is that I built an API that can never be, it was using async await everywhere and it can never work impossible. And I needed to change the API. That API was unsupportable. And so, there are, I'm sure there are people right now that are building their apps happily building async await everywhere into their app in a way that will never be compatible with concurrency.

And once those war so, and so this is really weird because Apple went from optional warnings to errors. This is, this is a mistake in my opinion. Leo Dion (host): well and I it's gonna take a while I feel like it's gonna take a while like I wouldn't be surprised if Swissx isn't even ready for dub dub 24 at this point Cuz Matt Massicote (guest): That's possible.

Leo Dion (host): like we like you said, I don't feel like it seems weird to go from optional warning to error to error I think at some point maybe in the next year. We'll see an Xcode release where Those are gonna become actual warnings Matt Massicote (guest): Yeah, and I think that if you are using, if you are using concurrency and don't have complete turned on, not just targeted, but complete, You're opening yourself up, you're opening yourself up to some really serious pain.

Because if you are building a system that cannot be compatible with this, what are you going to do at that point? And I think you want to know that now. So you want to have those warnings turned on, so you know right away at the beginning, Oh, I'm building something, but it's actually harder than I Leo Dion (host): yeah. And I'll I have a good blog post, I forgot who it was, who showed you how to turn those warnings on for Swift 6, and I'll put that in the show notes because it's really helpful.

Do you want to talk about well, one of the questions I had, do you miss anything regarding dispatch queue? It sounds like you do miss a lot as far as dispatch queue, is that correct? Matt Massicote (guest): I mean, I don't know if miss is the right terminology. Leo Dion (host): Yeah, I know.

I know. Matt Massicote (guest): I, I think that I don't think that for, I'm talking about for like complex use cases, I would be surprised if you can get away with using a concurrency in complex ways without using a current concurrency compatible lock and or queue. I think it's possible. I think some apps can do it, but I, but I, boy, I think you'll have a hard time. I mean, Leo Dion (host): You keep saying this stuff and I'm like, why, why not actors? What's wrong with actors?

Isn't that kind of what it's fundamentally Matt Massicote (guest): that's a great question. That's a great question. So, what are actors for? So actors protect mutable state, Leo Dion (host): Okay. Matt Massicote (guest): they, what they cannot do is they cannot control ordering of access to that state. So actors are Leo Dion (host): they can, but they're specifically for race conditions, right?

So you could, you're like, when you talk about a lock, like it's essentially what an actor is for, right? Matt Massicote (guest): yeah. So the lock is about re entrancy. So actors are re entrant, which means that the same object so that you can get the call into the same method multiple times, Leo Dion (host): Yeah. Matt Massicote (guest): more than one thread can be running inside of an actor, isolated method at the same time. Leo Dion (host): Say that one more time.

Matt Massicote (guest): So more than one thread, more than one thread can be inside, running inside of it. So, take a really, really simple example. Imagine you have a little cache, where you want to be able to like reach out to some service, and it takes a long time to get that value, so you want to cache it in an actor.

Leo Dion (host): Okay. Matt Massicote (guest): So you're probably going to do some little check if the value is op it's optional and if the value is there, I'm going to return it, and if not, I'm going to go do this await, and I'm going to get it, and then I'm going to return it. This is like a really classic caching pattern, I hope you're following what I'm talking about. That doesn't work with an actor.

Even something like that does not work with an actor, because between the check and the await call, another object can come in and make that call again. Leo Dion (host): See my thought, my whole idea with actor was that like it's basically a way to make sure that somebody can't like two people, two people, two, two threads can't do something to an actor at the same time.

Like I thought it was kind of like that where it was like essentially a cue where it's like Matt Massicote (guest): You know what? In a lot of ways, it is exactly like a dispatch queue. But the problem with, and it's the same kinds of problems with dispatch queues, where the dispatch queue, the body of the queue is synchronous. Leo Dion (host): right.

Matt Massicote (guest): So, and the same, it's the same kind of thing with an actor, is that the synchronous code, yes, is serial, and only one thread can be running in the synchronous code at one time. But as soon as you put an await in there, more than one thread can hop in there.

Leo Dion (host): Okay. Matt Massicote (guest): And so, and that's the danger, is that it's kind of similar to queues, where like, if you need to do some work in a queue and it's all serial work, you're safe, you can totally isolate everything. But if you want to hop out to some other queue, do some long work, and then get back into that queue, somebody else can get in, another thread can get into that queue at the same time. It's a very similar kind of problem.

Leo Dion (host): Okay. Matt Massicote (guest): And so, there's this wonderful package called semaphore that is a concurrency compatible lock and it lets you solve that specific problem. If you look at the actual implementation required to make something simple like a cash to value in an actor, it is bananas. It is bananas how complicated it is and it's because of this re entrancy. Leo Dion (host): okay.

Matt Massicote (guest): And a simple, a simple concurrency compatible lock, you cannot use the regular locks and semaphores. But a concurrency compatible lock makes it so much easier. It's worth it. Leo Dion (host): Okay. Yeah, I've actually had to use a dispatch semaphore for an async call because there is no, like, that's the closest thing to a semaphore I had in i i i in Swift. So, yeah, I feel like that's definitely something missing. Matt Massicote (guest): it is.

And so there's, there's one built, but the dispatch semaphore has a problem because of the concurrency runtime requires that all actors be able to make forward progress and a regular semaphore breaks that requirement. So you rest, you risk hangs using a regular kind of lock. Leo Dion (host): Was there anything you missed from dispatch queues? Matt Massicote (guest): So, so we're talking about locks here and all this why actors don't solve that problem.

So, but, so there's also, there's no mechanism. Actors, even if reentrancy is a thing, actor reentrancy is a thing that they address, which is being seriously talked about for Swift 6, because a lot of people are having this problem. Even if that gets addressed, it still does not help you with ordering. Or Leo Dion (host): Right, right, Matt Massicote (guest): stateful system, there's no way to control how things go. So there, you need a queue. A queue is a thing that you're going to need.

Leo Dion (host): Yeah. So like one of the things I think people, I actually, like I said, I think it's a feature, it's a bug because one of the things that I had to learn is that when I first started async await was that I assumed in a function, when you run a bunch of async stuff in a function, it was going to do it in in, not in an order. So I'm in like the opposite boat. And then I learned, Oh, if you want things to not run in an order, then you have to do like the async let.

In order to do things in a non order. This is not what you're running into. You're Matt Massicote (guest): No, I, yes, that is, that is confusing. You're right. Leo Dion (host): Because I was like, I don't, like, these things don't depend on each other. Compiler, please just run it in whatever. Like, run them all together. I don't care. And then I was like, Oh, you have to do this async lat, which is totally not... Like, that's a little bit weird to Matt Massicote (guest): I agree with you.

It Leo Dion (host): Because it's like, the whole point of async away to me is like, I don't, these things don't, unless they depend on each other, and I figured the compiler can figure that out, I don't need to tell it, like, it should, it should just run it in whatever order, I don't care, like, so that was one of the things I first had to, had to learn is like, oh yeah, use this async let to let it know that I don't care the order.

Matt Massicote (guest): Yeah. Well, you can do that for things that are, have no dependency. So if you're doing like ABC and they don't matter, then you can do that kind of thing. But if you have like, you're going to do a, and it's an async call, and then you need to use the result of that in B now the ordering is required. So within a particular context, within a particular async context, it's all going to run things in order.

Leo Dion (host): right, by default, Matt Massicote (guest): these contexts. Leo Dion (host): around, which is your issue, where you have Function over here and function over there. Yeah, yeah, yeah.

Matt Massicote (guest): And I think that's, so that's one of the reasons why I think there was this deep misunderstanding even internally at Apple is the, when, when async await was originally introduced, there's this automatic translation that you can use between a a completion Leo Dion (host): handle her. Yeah. Refactor and Xcode. Yeah. Matt Massicote (guest): it'll just like magically make it work.

And I think that is, that was done because I don't think there was a deep appreciation for how dangerous that kind of thing can be. Because that kind of change can be so, if you're thinking, oh, I'm just going to change it into an async an async await, and I'm going to wrap it in a task, that it has different semantics. And so you're changing, when you make these refactors, you're actually changing the semantics of how the code works as well. Leo Dion (host): Yeah, yeah, totally.

Matt Massicote (guest): And I'm not sure everybody understood that one. Leo Dion (host): it seems like you're looking at some of the SWIFT proposals. What do you see out there as something you're looking forward to that kind of remedies some of these issues? Matt Massicote (guest): Oh, well, there's a, there are many changes that are out there. So one really difficult one that I think is also pretty hard to understand, even before concurrency was out there, is needing to do stuff in a D init.

So in your dinit method, if you have a main actor thing, you're thinking, okay, my dinit is going to run in the main actor too. But that is actually not the case. And I think that is really surprising to people. Even from objective C, you might think like, how could it be my view is being deallocated, not on the main thread? That's, doesn't seem right. Leo Dion (host): Even if you, like, even if you mark your whole type as, or class as main actor, it's still not gonna run, didn't it?

Okay. Matt Massicote (guest): yeah, yeah. And this is, this can be a really big problem for certain Leo Dion (host): I would Matt Massicote (guest): Yeah. Yeah. And I don't know that they have fully sorted out what they're going to do about it, but it is an understood problem and it cause UI kit.

I don't even think this is well known, but UI kit and UI view in particular, it goes through these Herculean efforts to try to make sure your D in it, or your, your dialect actually does run on the main thread. Leo Dion (host): Okay. Matt Massicote (guest): But it requires an enormous amount of work at the app library level to make it happen. Leo Dion (host): Okay. Matt Massicote (guest): And so I think that they're trying to solve this problem and I think that'd be wonderful.

But I don't know yet if there's currently any solution out there. Leo Dion (host): Okay. Matt Massicote (guest): So that's one, that's one that's being talked about. Well, there's this whole property wrapper changing actorness. That's a, that's a really confusing one. I'm really happy to see that one has been accepted and it's gonna, gonna happen. Leo Dion (host): Okay. Have you looked at any of the observation stuff? Does any of that? Okay. Matt Massicote (guest): to, but I haven't seen it yet.

Leo Dion (host): Okay. Okay. Matt Massicote (guest): I mean, there's also things that are tangentially related to async await. Like. I have had a really hard time using async sequences. Leo Dion (host): Okay. Matt Massicote (guest): of, one of the reasons why is async sequence does not have a primary, the protocol does not have a primary associated type. So you can't use any async Leo Dion (host): Yeah, nah, Matt Massicote (guest): You can't use any async sequence. Leo Dion (host): right.

Matt Massicote (guest): And so that's usually not a big deal unless it's at an API boundary. Leo Dion (host): Okay. Matt Massicote (guest): And then it's an enormous deal because what type are you supposed to return? Leo Dion (host): Okay. Yeah. Yeah, that's weird. Matt Massicote (guest): it is weird. Yeah. Leo Dion (host): because they slapped on primary associated types so many places. It's so weird that Matt Massicote (guest): you know, it was, it was, it was intentional.

And the reason why was they were thinking about how they were going to expose the error property of async sequence as well. And I think that's what caused the hook, the hangup. But I would love to see it. I would love to see it because that's, that's been a problem for sure.

Leo Dion (host): and I'll put a link to my talk at Swift heroes somewhere in here So people can check that out if they want to know why primary associated types are so important was there anything you looked at at DubDub DC this year? You said, you said a few things, like what specifically? And anything that related to Chime I guess? Matt Massicote (guest): Well, you know, I was hopeful for some more extension kit changes.

There's a few little things that have been problematic, but there was nothing there. No, there was nothing really. I mean, I'm always interested in what goes on with the text system because there was this big migration from TextKit 1 to TextKit 2. And I would say that that has gone largely. Terribly text kit two is, is getting better, but it is so it was, it was launched in an absolutely unusable state. I'm amazed that it, that it chipped. That was with, I think that was Mac iOS 11.

So that was two years ago. Last year it got a lot better. But still has some really major bugs that I don't know how to work around. I haven't tried hard, but I know that it's a problem. So I was hoping for a little bit of talk about like what's new in the tech system and maybe some changes that would help. I didn't see anything there. The things I did see, I think the macro stuff is fascinating. Leo Dion (host): Mm hmm. Yeah, I agree.

Matt Massicote (guest): a lot of people have started to feel a little bit like Swift is getting to be too complicated of a language. And it's complicated. But yeah, but I, I think that it's, I think it's a very interesting direction to go in anyways. These are the fundamental problems, they have to be solved somewhere. And so I like the idea of people thinking deeply and trying to come up with a, a solution in the language.

Leo Dion (host): I have an idea for a talk here about how complicated Swift is. I, it's, it's been floating in my head, but yeah, I have an idea for a talk I want to put together on why people should try not being too intimidated by it and, you know. Anyway. You'll see that in the future. Future, in the future, soon. Cool. Is there anything else you wanted to cover about Async Way about Chime before we close out?

Matt Massicote (guest): Well, you know, so, last year was all about me adopting extension kit and building this API that was never going to work. And then this year, kind of in the background, I've been slowly chipping away at fixing it. And I can say that it's, it's been incredibly difficult. And I think the reason why it's difficult, one is that actorness is very viral. So if you find there's this one little thing you need to change to be main actor, it's a big, it can be a big problem.

So that's one thing another thing is, you know, you got to be careful with protocols because protocols and actors and even main actor isolated objects don't always mix. And I think that we've been very, as like a swift community have been very quick to use protocols everywhere. And that can be problematic when when adopting concurrency. So that was a one that was tricky for me. But I have, I'm pretty close actually. So I, I'm almost finished.

Updating an enormous amount of packages and a big API surface to actually be something that works correctly and concurrent with concurrency. And is I think also what I want. So I'm very happy with that progress, but it's been very tough. Leo Dion (host): awesome. Well, I am excited even though I won't be in Toronto, I'm excited that you'll be presenting on this topic and telling people all the lessons that you've learned. I think it's gonna be awesome and fascinating.

Matt, thank you so much for coming back on the show. I really appreciate it. Matt Massicote (guest): Absolutely. Thank you for having me. Leo Dion (host): Where can people find you and Chime online? Matt Massicote (guest): Well, Chime is at ChimeHQ. com. And I've just finished removing all of the bird site references, so you can find me on Mastodon. You can find me on Mastodon. social slash at Maddie M. Leo Dion (host): It's on a bird site today.

Today, as of the recording, it's, it's an X site, so you actually have, I'll have to, yeah, I'll have to fix, I'll have to fix this in editing, make sure that people know it's the X site, not the bird site today. People can find me on the X site at LeoGDeon but I'm also on Macedon at LeoGDeon at My company is bright digit. Please take some time. If you're watching this on YouTube to like, and subscribe. And if you're listening to this on a podcast player, please give me a review.

If there's anything you want to talk about or anything you want to hear about, let me know, DM me, email me. Send me an X, I guess. I don't know, whatever it is. But and also buy a ticket to Swift Toronto if you haven't already, hopefully this episode will be out in time for you to do that. Thank you everybody. And I look forward to talking to you again. Bye everyone.

Transcript source: Provided by creator in RSS feed: download file