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.
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.