An exploration of Apple business news and technology. We talk about how businesses can use new technology to empower their business and employees, from Leo Dion, founder of BrightDigit.
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.