Episode Transcript
Available transcripts are automatically generated. Complete accuracy is not guaranteed.
Leo Dion (host) (00:03):
Thank you for joining
me for another episode of Empower Apps.
I'm your host, Leo Dion.
I'm joined once again by Matt Masicotte.
Matt, thank you so much for coming on.
Matt Massicotte (guest) (00:12):
Thank
you very much for having me again.
Leo Dion (host) (00:14):
This is
number three appearance.
People probably know you, but I'll letyou go ahead and introduce yourself.
Matt Massicotte (guest) (00:20):
sure.
Well, my name is Matt and I'm along time Apple developer, and
lately I've been putting a lot ofeffort apparently into concurrency.
It's like my main thing.
Leo Dion (host) (00:30):
So
you were on last time totalk about concurrency.
You're back on to talk aboutconcurrency and the future of Swift.
Yeah.
Where,
let's just jump right into it.
Where do you think concurrency isat when it comes to Swift 6 and how
things went with Swift 6 and actorsand a weight and all that stuff?
Matt Massicotte (guest) (00:52):
Well.
I think that most people are gonnahave trouble adopting Swift 6, And I
think a lot of people kind of naturallyare trying to do it because it's this
new thing and it's been released.
And so because it's released, it feelslike it should be the thing that we use.
But I think that for thevast majority of projects,
(01:12):
Swift five mode is the right
thing to choose and then tojust incrementally work your way
towards going in this direction.
Leo Dion (host) (01:21):
What if you're
starting a brand new product?
Matt Massicotte (guest) (01:24):
I think that
if you're starting something brand
new, especially like with No, ifyou're starting with nothing carried
over, then sure go for Swift 6.
It's usually a lot easier to doit with a new project than it
is to migrate existing stuff.
That's really
the big problem I think.
Leo Dion (host) (01:39):
Okay.
Do you think where do you see theissues as far as, for the most part, for
people's mental model of how they thinkit works versus how it actually works?
Matt Massicotte (guest) (01:49):
you know,
the big thing that happened, and this
happened to me, and I think it happenedto a lot of people, and I still see it
happening now, is they're using asyncweight, as a syntactic convenience,
over completion handlers, I.
it feels that way in a lot of ways.
And so you might likehave an existing project.
All the warnings are off by default,and you just start saying like, oh,
instead of having completion handlerseverywhere, I'm just gonna use async
(02:12):
weight, then it's all gonna be the same.
And that is not truein the general case.
And there are very trivial exampleswhere that will change not just how
the code looks, but it will changethe semantics of how it works as well.
so when people get themselves, like whenyou were asking about a new project,
you can kind of catch yourself fromthe beginning because Swift 6 mode will
present errors as soon as you make a.
(02:34):
Swift five mode, especiallywith no warnings for the most
part, won't show you anything.
So it's very easy to make thesechanges that are mostly correct and
mostly fine, and you start havingthis big project that is adopting
more and more of this stuff.
And when you finally do flip onthe warnings or try to use Swift
6 mode, you'll inevitably discoversome stuff that isn't right, and
that's when it can be hard to fix.
Leo Dion (host) (02:55):
So I have
a few thoughts about that.
It's interesting yousaid syntactic sugar.
'cause that's exactlywhat I had thought before.
Async away had come.
I had thought that's essentiallywhat it was gonna be, was kind of
like promises underneath, but like
basically
it's still not changing a
lot.
(03:16):
So my first question is the problemsthat Swift 6 addresses when it
comes to concurrency were thoseissues that had already existed,
but we didn't notice under GCD?
Matt Massicotte (guest):
Well, well, like one example (03:29):
undefined
is you have some API, right?
And it's got some callback and it says.
And you need to know, well, does thatcallback happen on the main thread or
do I need to dispatch over to the mainthread to, to handle that callback?
And so that's a really common patternwhere many people will just not look at
documentation, not read how things work.
They'll just always put a dispatchto man, and That's safe because
(03:53):
then you never have to worryabout whether you're being called
in a background threat or not.
It is also inefficient, but itkind of shows you, it highlights
the general problem of.
if you miss that in even onesingle spot where you happen to
not realize some API is callingyou back on the main thread and you
don't put that that call back in.
Then inevitably you'll run into problem.
and this is like areally common problem.
(04:14):
I'm sure you've had thisproblem happen to you as well.
a super common problem.
So that's one of thethings that concurrency.
Swift concurrency fixes is because thatthe, this information of like, should
this be main thread or not, is builtinto the signature of the function.
You cannot get it wrong.
You don't even need to think about it.
You just like run your code and it'llautomatically do the right thing.
(04:35):
So from that perspective, I love thatbecause that's a really common problem
Leo Dion (host) (04:39):
we talked
about previously in the last episodewith Donnie about the whole having
to mark things as main thread and theplan to like change that going forward
for like, if you call something from
main thread, you call it async function,
from the main thread, there'slook, they're looking at
like proposals about that.
(05:00):
Do you know what I'm talking
Matt Massicotte (guest) (05:01):
Yeah.
Leo Dion (host) (05:01):
You wanna
just kind of explain what that
is and what it's supposed to
address.
Matt Massicotte (guest) (05:06):
Well, there's
a lot going on there a lot but like
one of the things is you had said,and I thought too, that async weight
was just syntactic sugar for callback.
And that is true provided that theisolation of the types involved don't
change.
Leo Dion (host) (05:20):
right,
Matt Massicotte (guest) (05:20):
And so, and,
but what's interesting is there was
this proposal that was introduced,I don't know, like Swift 5.7 or 5.8.
I can't remember exactly what it wascalled, but it changed the semantics
and it very clearly specifiedthat if you have a non-isolated
asynchronous function, it's alwaysgonna run on the background.
But What that did was it fixed a coupleof performance issues, but it made it
(05:41):
so it was no longer true that thesethings are just syntactic, sugar for
completion handlers for most uses.
And so that one little change endedup having widespread implications
to make it really hard for peopleto do the right thing unless they
deeply understood this implication.
But that is gonna get changed.
And just that one change,
Leo Dion (host) (06:02):
That is actually gonna
get a change.
Matt Massicotte (guest) (06:04):
well it's
being, it's in, it's being worked on,
but it, hasn't actually been,it hasn't actually been formally
pitched or formally proposed yet,but I think it's going to be.
But I bring that upbecause talking about.
How all this works, there'sa lot of lack of intuition.
So the, how you might expect thecode to work and maybe how you
have code written that works today.
(06:25):
It will like start workingright when this has changed.
It has a bunch of otherpositive impacts as well.
I mean, I think this is, thiswas a very I'm not sure why
this change was made originally,but I am looking, forward to it
being undone.
Leo Dion (host) (06:37):
Okay.
Okay.
So what are some other misnomers
that you've seen people pick upwhen it comes to concurrency lately?
Matt Massicotte (guest) (06:49):
Well,
so one is like not understanding
the implications of asynchronous.
functions.
This is what we're talking about.
Leo Dion (host) (06:54):
and I think that
the whole like isolation stuff
like.
When it was first introduced,actors were just like, yeah,
I'm not dealing with that.
I don't want to have to deal with it.
And then like the moreand more I deep dived into
Async away, I was like,okay, yeah, I need to know
how this stuff works.
Because like you said,it isn't syntactic sugar.
(07:14):
There's a lot going on there, especiallyconcerning isolation and like, I mean,
essentially what we're getting at
is like, not.
Dealing with race conditions,
right?
And stuff like thatwhere you don't want two
people doing the same thing
and messing stuff up.
Or two people, two actors I should say.
And I think that safety, that threadsafety was something that I think we
(07:38):
didn't realize needed to be done thatwasn't being taken care of in Swift.
And it's like augmenting.
Part of what makes Swift so great isthat safety, and so for me that was a
big revelation in a lot of the work thatyou've done has been a big revelation
as far as like what Swift 6, what asyncaway and what actors are trying to do.
Matt Massicotte (guest) (07:59):
Yeah.
I mean, it's, that's the onlyreason it exists is to do safety.
It's also nice.
I mean, I like that.
You no longer need to check thedocumentation to figure out is this.
thing being called on the main thread?
Do I have to use this thingonly on the main thread?
It's cool that You don't have to lookat documentation anymore, but the big
focus was was, safe, was around safety.
You're absolutely right.
Leo Dion (host) (08:18):
So actors, I mean,
is it come down to like actors being
the big challenge when it comes
to async away and isolationmore so than the, like,
not concurrency, but
Like, is that where it really
comes down to?
Matt Massicotte (guest) (08:34):
I think
the challenges people run into is
taking their existing code thatuses, that doesn't use concurrency
primitives, or, and this is worse,uses concurrency in incorrectly.
And then when they wanna move that toa warning free or error free state.
But if you're starting withsomething that, like you have.
Absolutely no asy weight in your codebase and you just want to start like
(08:56):
seeing where the warnings show up.
It's not usually that bad to startexpressing the reality of your code.
to the compiler, for example, addingthings like this is unchecked sendable.
this is non-isolated, unsafe, likethere are all these called opt-outs,
these tools that you can use to tell thecompiler, I am doing the right thing.
You don't need to check this stuff.
Now, the advantage of thatis That gets you really far.
(09:18):
And the disadvantage of it isit turns off all the checking.
So like, I'm not sure.
if you were saying what I wanna dois use Swift 6 with no errors and
have all these popped out, turned on.
I just, I don't know whatthe advantage of it is
really.
Leo Dion (host) (09:32):
right.
Matt Massicotte (guest) (09:33):
unless
there then, unless you wanna
start now in the future, movingtowards not doing that anymore.
I.
Leo Dion (host) (09:39):
Right.
Right.
So let's talk about that.
Where is using unchecked send?
Well, let's try it withunchecked sendable and then
we'll move to pre concurrency.
Where do you think it's usefulto use unchecked sendable,
Matt Massicotte (guest) (09:52):
Well,
Leo Dion (host) (09:53):
yeah, that's okay.
Matt Massicotte (guest) (09:54):
imagine you had
some class that you made that is like a
dictionary plus a queue, and it's justthis thread safe version of a dictionary
or a cache or something like this.
Just some thread safe type thatyou're using for whatever reason,
but it protects all its state.
Internally, I.
that thing is unchecked, sendable.
You make it unchecked,sendable, and you're done.
Leo Dion (host) (10:11):
Okay.
How
about, is there ever an instancewhere you just don't care?
Matt Massicotte (guest) (10:19):
you don't
care whether it's safe or not?
Leo Dion (host) (10:20):
Yeah.
Yes.
Matt Massicotte (guest):
Probably that's true. (10:22):
undefined
And I think really I think thereare many people that have come to
Swift concurrency saying, well,I just think my code is fine.
I don't understand why do I haveto deal with this stuff at all?
And I think the end.
Today the answer to that wouldbe then turn off the warnings.
Use Swift five mode, andthen you're mostly, okay.
There are a few bugs that are currentlyexist in the Swift 6 compiler that
(10:43):
make it so that even if you do turnoff everything, you still see some
warnings in certain circumstances.
But I think it's relativelyrare but that's not usually
what people are seeing.
What people usually are seeingwhen they get frustrated is
they're using concurrency, they'reusing it incorrectly, but they're
getting frustrated because theyjust want The warnings to go away.
And the solution to thatthere is no solution
(11:05):
to that 'cause you can't use theconcurrency system, but then have it
not tell you that you're using it wrong.
Leo Dion (host) (11:09):
Right, right.
That's a whole point.
I mean, so are the gains by usingit correctly, like performance
or what do you get from switchingover to Swift 6 doing and doing it
right, as opposed to Swift five?
Matt Massicotte (guest) (11:23):
Well,
I guess so I'm interpreting
your question to mean you'remigrating from using something
like GCD to using the concurrency
primitive,
And
in that case there are somepotential performance gains.
So this huge emphasis was put whenSwift concurrency was first introduced
on like reducing context switches.
And the idea there was, instead ofhaving your code bouncing around between
(11:44):
different threads, you have these,this small set of thread, pool thread.
pool Threads And then this workcan be divvied up without actually
necessarily needing to hop aroundand or spawn different threads.
So G, c, D and concurrency, one ofthe things concurrency was trying
to do was address this problem.
And you can see there's A-W-W-D-Ctalk that goes into like depth
about the idea behind this.
Leo Dion (host) (12:05):
Okay.
Matt Massicotte (guest) (12:06):
Now I'm
kind of trying to focus on the
idea because in practice I've donezero really investigation into.
this.
So I don't know for a fact thatyou will see performance gains or
losses by making these changes,but that's one of the ideas.
Leo Dion (host) (12:20):
You're
gonna say
another one
Matt Massicotte (guest) (12:21):
Yeah.
Well, the main, but the main focusof it was not so much performance
as it was being able to useconcurrency without having to even
really think about whether or notyou're introducing data races.
That was really the big
Leo Dion (host) (12:33):
Right, right.
So, I mean, to me, like the emphasis onconcurrency was always the fact that,
I mean, we could get into it, but whenI did my talk at 360 Ida a few years
ago about the future of like asy, this
would've been 10, almost 10 years ago.
Geez.
But the idea was, is likea, we don't, we wanna do
(12:54):
async away for the syntacticsugar, but also the fact that
like, I don't wanna say we'vehit like the edge of Moore's law.
I don't know where you're at on that,but the fact is we moved away from like,
you know, getting faster and fasterprocessors to just having more and more
cores.
And the fact that you can divvyup jobs to multiple cores makes
(13:16):
it more advantageous to want to
do.
Things on
more cores as opposed to like,just like, because you can't,
your processors aren't gonna get
faster per se, as much as youget more cores and can do more
things at the same time.
And that's where the advantage is.
Am I mistaken in what I said or
like, like is that thebenefit of concurrency
(13:39):
or doing things concurrently or is
it like with context switching?
Is it
just creating more work than it's worth?
Matt Massicotte (guest) (13:46):
Well, so
one thing I'll say is single-threaded
performance has been gettingsignificantly better year over year
and continues to.
I don't know that will continue forever,but it certainly has been the case.
Leo Dion (host) (13:57):
Okay.
Matt Massicotte (guest) (13:58):
So it is true
that like, generally speaking, there's
been more cores per processor over time.
That's true.
But also, even if you don'tuse any concurrency at all and
just have a single threadedprogram, they're also getting
Leo Dion (host) (14:10):
Okay.
Okay.
Matt Massicotte (guest) (14:12):
Now, you know,
I think that one of the things that
I've seen people do with concurrency islike this, it's almost like this fear
of the main thread that they wanna get
everything
Leo Dion (host) (14:23):
I like that.
the
fear of the main thread.
Matt Massicotte (guest) (14:26):
Well,
it makes sense because it
makes your app unresponsive.
So the idea is you want to get allthat work off the main thread so
that you can have it be available toservice user input or other kinds of
events.
But the thing is that it is,there's overhead, So moving
something off of the main thread,even to one of these, to any to
anywhere, It has a little bit of a
(14:47):
cough.
It's usually
Leo Dion (host) (14:48):
And this is,
you're talking about the context
switching.
Matt Massicotte (guest) (14:51):
Yeah, exactly.
It costs it, it takes some amountof work for the computer to be
able to no longer run this stuffon the main thread and do it
somewhere else.
And so as long as the work you're doingoutweighs the cost, then it's a win.
But if it turns out that the workthat you're switching off of, the main
thread is minuscule, is teeny, likea very small amount of work, you're
(15:11):
doing it off of the main thread, soyou're transferring the work off.
and now you have to deal with,and now my user interface can
still accept input, right?
So I have to maybe like turn offa button or put a spinner and then
you finish and now you have to movethat work back onto the main thread.
So there's overheadand extra complexity.
And as long as it's worth it, it's good.
But I, I've encountered certainly anumber of applications where they're
(15:32):
shifting these minuscule amounts ofwork off of the main thread To do
basically nothing and then move itback onto the main thread, which causes
significantly more complexity for,it's actually a negative performance
benefit.
It's faster to just stay on themain thread and do it all there.
Leo Dion (host) (15:47):
That's
really interesting.
I don't think a lot of people knowthat, Matt, like, I think a lot
of people think, like you said,oh, we should just have it all.
On the background and then onlyhave the stuff that involves
UI updates on the main thread.
So I agree.
I don't like it Makes sense.
It makes sense what you said andI think a lot of people don't know
(16:08):
that.
Matt Massicotte (guest) (16:09):
Well,
I think they, I think that
their intuition is so close.
I think people are really, have theright idea, which is your fear should
be of long running synchronous work.
If you have anything, like takethe super classic example is
you're gonna download some J fromthe internet, you're gonna decode
it and turn it into some model
or something That J is probablynormally small, maybe it's even tiny.
(16:30):
And it's true.
If you do the decoding andparsing on the main thread,
it might actually be faster.
but only for that particular input.
In the general case, you couldget these massive blobs adjacent,
take a long time to decode.
So those kinds of things, theymake sense to offload to a
background task and then to pop
back
Leo Dion (host) (16:46):
Okay.
Is there anything else we'relooking at as far as the future
of Swift in concurrency goingforward with six one or six two
Matt Massicotte (guest) (16:56):
I
mean, I'm,
Leo Dion (host) (16:57):
the other
thing.
Matt Massicotte (guest) (16:58):
well, six
one, I'm very excited about six,
6.1 because there's a whole bunchof bugs and I guess I'll call them
limitations in the existing six pointwhatever, three compiler that 6.03.
That I just I'm lookingforward to seeing.
them
Leo Dion (host) (17:13):
All right.
Matt Massicotte (guest) (17:14):
There was a lot
there was a lot of new featuresadded with Swift 6 and some
of them don't, aren't quite asrobust as I think they should be.
And I think that 6.1 isgonna do a lot to fix that.
Leo Dion (host) (17:24):
Are they concurrency
related?
Matt Massicotte (guest) (17:26):
Yeah.
Yeah.
I'm only talking
Leo Dion (host) (17:27):
Yeah.
Yeah.
Yeah.
What are they?
Do
You wanna talk about 'em?
Matt Massicotte (guest) (17:30):
Well,
for example, there's this
new keyword called sending.
And sending is like, you can think aboutit as this lower bar than sendable.
The whole type needs to be thread safe.
And sending is morelike just this one spot.
In this one case, I'm gonna make it bethat can the compiler prove this is it?
So sending is really wonderfuland it really is this great
tool except I have found many.
(17:52):
limitations where the compileris Oh, Too aggressive too.
Too conservative in avoiding using it.
And so it lets, it doesn't letme do the thing, even though
I'm pretty sure that it should.
And there's a lot of bugs that havebeen filed about this and many of
them are fixed, but just not yet really.
Leo Dion (host) (18:07):
Okay.
Yeah, we just talked about thatin the last episode with Donnie.
That, so I wanna talk
about that little is this whole
world of like perimeter.
Perimeter argument, prefix it words,keywords that I'm like totally not
familiar with.
So like, so like with thenon copyable stuff that I
(18:28):
talked about at ww dc right?
They
introduced a few, andthen we have sending,
and then we have isolation.
Like kinda,
Especially
the isolation one, I stilldon't understand how that is
supposed to be used in a method.
Signature.
Matt Massicotte (guest):
I think that's good. (18:46):
undefined
You shouldn't need to understand it.
And as soon as the, as soon as thenon-isolated async change happens, which
I hope it does, you won't even need to
Leo Dion (host) (18:53):
Okay?
Okay.
Matt Massicotte (guest):
Un unfortunately, we're (18:54):
undefined
not in that place today.
Today.
It's a critical tool for certainkinds of problems where you really
Leo Dion (host) (19:02):
You wanna
explain what those problems are?
Matt Massicotte (guest) (19:05):
Well, I
mean, what it really comes down to
is if you wanna add a asynchronousfunction to a non sendible type.
You can't really pull that offwithout understanding how, I mean, I
think you're talking about isolated
Leo Dion (host) (19:19):
exactly.
100%.
Matt Massicotte (guest) (19:20):
yeah.
Yeah.
You can't really pull that offwithout isolated parameters.
And so like a common thing I haveseen people do is they'll take
some type that they don't control.
It's from some library somewhere,and they wanna wrap up something
that the library provideswith an asynchronous function.
If that type that you're wrappingup though is not sendable,
you can't really do that.
Leo Dion (host) (19:40):
Okay.
I know exactly what you're talkingabout because when I bug you on Slack
one of the things lately that I've beenbugging you about is the virtual machine
stuff and like there was somethingspecifically related to that.
I think it was like
either starting, well it's weird 'causevirtual machine, or virtualization,
(20:00):
I should say framework has abunch of async weight methods.
But then they're classes andthey're not really sendable and
it's like kind of a
mess.
Matt Massicotte (guest) (20:11):
Okay.
Well actually wait, so is that,but that framework is an objective
Leo Dion (host) (20:14):
Yeah.
Yes.
We've talked about
this offline.
Matt Massicotte (guest) (20:17):
Okay.
So, So, that's important because thecomp, well, I don't know the history
of this or why this happened, butthe compiler does this automatic
translation to in both directions fromasync to completion handler, and then
Leo Dion (host) (20:31):
Because it's
same tactic, sugar mat, so that
makes total sense.
We just talk.
Matt Massicotte (guest) (20:34):
Well, I
think, okay, so this is speculation.
My speculation is what happened isthat was added before the change to
non-isolated asynchronous methods wasmade, and that was added to the compiler
and then they changed this, which causedthat translation to not work properly
and they left the translation in.
I'm not sure why that was done.
Leo Dion (host) (20:52):
documented too.
So it's like it's not an accident.
It's like they actually document it in
the, like if you go to the
Apple documentation, they ha,
Matt Massicotte (guest) (21:03):
I know.
Yeah, I've seen it.
It's just, it's not a safe thing to use.
You can't really use thecompiler bridging from,
Async to completion handlers.
Leo Dion (host) (21:10):
oh my gosh.
This
is what drives people crazy.
Matt Massicotte (guest) (21:14):
Yeah.
I mean, that should, that's a tough one.
I don't
Leo Dion (host) (21:16):
And I get, the
translation right, because we've done,we've gone through this crap before
with like, like you could do syntacticsugar and objective C for generics and
you could do stuff for like throwing.
So yeah, that makes total sense.
And then what you're tellingme is like they are treating
it like syntactic sugar and
this translation stuff,
but in fact they're not taking intoaccount the ramifications of what that
(21:40):
really means.
Matt Massicotte (guest) (21:41):
Well, I
okay, so the most charitable point
of view on this is, it's not thatit's wrong, it will work, but
only in very narrow circumstances.
I.
So it could be that the reason thatit was left in was because it still
can potentially work sometimes.
It just depends on your usage andif you use it wrong, it will be
caught with warnings and errors.
(22:03):
So it could be, and again, I'mnot sure this is the case that
it was left enabled because thatyou can use it correctly provided
you follow the warnings and use
Leo Dion (host) (22:15):
I mean.
I've never gotten a single warning
about running any ofthose methods, so like,
Matt Massicotte (guest) (22:22):
If they're
non sendable types, then you
should receive a warning if youcall it from an isolated contact.
Leo Dion (host) (22:29):
I don't think I.
Matt Massicotte (guest) (22:30):
but
it's possible you aren't.
So if you aren't doing that.
then that's an exampleof where it could work.
Leo Dion (host) (22:35):
fair enough.
Matt Massicotte (guest) (22:36):
So, so like I'm
not saying, I'm not saying that, they.
I'm not saying that the objective casync translation stuff never works.
I'm saying that it is, you have toreally understand what's going on.
If the
types are
Leo Dion (host) (22:49):
ever look in objective
C if they added any documentation for
like, how it should be translated?
Like can you put any macros or
like things in it?
Matt Massicotte (guest):
you can, There's tons. (22:58):
undefined
so there's tons of of clangannotations you can use to put
things to put annotate Swift onlyannotations in your objective C code.
That Those all
Leo Dion (host) (23:09):
Okay.
So is there something todeal with the situation?
Like let's say you're, you have someold objective C code and it's out there
and you wanna make sure thatno, don't create a async
away version of this
completion handler.
Is there a way to,
Matt Massicotte (guest):
Yes, you can suppress, the (23:23):
undefined
comp, the the async version.
You can also do things like, you canadd at sendable annotations to closures,
which is a very important thing to do.
You can do that from objective C.
You can mark types as sendable asmain actor, and you can do pretty much
everything in terms of annotations with.
From Objective C Codethat you can do from
Leo Dion (host) (23:40):
Okay.
So we, talked about this, likein my case, would it be useful
to use pre concurrency onthe virtualization framework?
I.
Since it's
Matt Massicotte (guest) (23:52):
I would
have to look more closely at it
to say with confidence,but it's possible so.
Leo Dion (host) (23:55):
So yeah, go ahead.
What would be a good case for whereyou want to use pre concurrency?
Matt Massicotte (guest) (24:00):
Well, okay,
so let's just pretend that, we won't
talk about virtualization 'cause I'mnot sure, but you have some library and
it has let's say it's in objective T,It hasn't had any updates whatsoever.
So today in your Swift five,no warnings World, you have
to use it correctly, right?
if the things have to becalled on the main thread, you
have to, run the main thread.
If you have to supply your ownqueue, you have to use it correctly.
(24:22):
So if you import precon.
What you're telling thecompiler is, I am using this.
Right?
Stop complaining about thetypes that you can't tell.
So when you import a frame, thatframework with pre concurrency,
you're basically telling thecompiler what I'm doing is fine.
But that's not necessarily the case.
But as long as it is, as longas your code is right today,
(24:42):
then import pre concurrency.
Makes sense.
Unfortunately, one of thedisadvantages of it is that
it applies to the entire file.
So some what's happened to mesometimes is I'll have like one,
I'll have a big complicated classand it's got one little use of a
framework in one spot, and that typethere is not sendible, but I know
I'm using it safely.
Now, if I import thething pre concurrency.
(25:04):
I could later accidentallymake a mistake and the
compiler won't warn me
Leo Dion (host) (25:08):
Because
it does it to the
whole
framework.
Matt Massicotte (guest) (25:11):
Yeah,
it does the whole, it does the
whole framework in that file.
Yeah.
So what you, can do is separateout just that one usage.
You can even do this with extensions.
You can like split aclass into multiple files.
So it's kind of gross to do that,but that is maybe a thing you
want to
Leo Dion (host) (25:26):
So basically put
that little one use in a separate
file in an
extension.
Okay.
Matt Massicotte (guest) (25:31):
Yeah.
If you're really worriedabout it, then that.
makes sense.
I mean, I've also seen the oppositecase where there are people
that are using code wrong today.
They turn on the warnings,they discover the compiler is
unhappy all over the place.
They throw a pre concurrency onthere and all the warnings go
away, but the code's still wrong.
Yeah,
Leo Dion (host) (25:47):
You had a
really great blog post about why
you don't need to make
everything sendable.
Maybe you wanna like quicklysummarize that and where people
fall fail in that aspect.
Matt Massicotte (guest) (26:00):
Well.
A thing that happens is that youturn on warnings and immediately
you're gonna get a lot of warnings.
That reference sendible, thistype is, I sendible you can't do
this 'cause it's not sendible.
And so your reaction, you're verystrongly pushed towards this direction
of just make the stuff sendible.
Everything works so nicelywhen things are sendible.
So it's a very normal, I think, tohave that kind of feeling, especially
(26:22):
if you don't really you're justgetting started and you're getting
started with an existing code.
base.
Usually, I think what you want todo is like, think harder about do
I want this thing to be sendible?
Why does it have to be sendable?
Does maybe I'm I shouldn'tbe bouncing this stuff around
between lots of different act,lots of different threads.
Like maybe it should all stay on one.
(26:42):
And so, I my, my go-to is alwayscan we like not need this thing
to be sendible in the first place.
That's a
better
Leo Dion (host) (26:49):
for me, like,
this is where you'regonna tell me I'm wrong.
cause that's what this whole
episode's gonna be about.
So for me, like Sendibleis basically like if it's a
struct to where it's just data.
Like it's okay to
just make all those sendiblebecause they're simple enough and
who cares.
Whereas classes, I wouldnever make a class.
(27:10):
I would like try really hard,
never to make a class sendible.
Matt Massicotte (guest) (27:13):
No.
you're, I think you're right.
that's totally the rightway to think about it.
Leo Dion (host) (27:17):
Classes should
never be sendable because
they're reference types and
that's a mess Waiting to.
Matt Massicotte (guest) (27:22):
I mean, I
Leo Dion (host) (27:22):
Not
never, but
like it's a lot of work to
make a class sendible.
Like if you're.
Matt Massicotte (guest) (27:29):
Okay.
So, but that's the key, what you justsaid there is the key is that if you
have to do work to make somethingsendible, that's a strong signal.
You probably don't
Leo Dion (host) (27:36):
If it has
to be used, what basically wouldI've come, what I wrote in my
blog post was basically if it'sa struct and it's fairly like
just data types, then yeah, go
ahead.
You can make that sound,you should make it
sound kinda like you to make itquotable or you make it credible or
something simple like that.
Whereas if it's a class andyou really need it to be
(27:57):
sendable at that point, you mayas well just make it an actor.
Because then that way, like youare, you're taking care of the
fact that like you'll never have aninstance where you can't write and
read essentially at the same time.
And actors kind of
handle that.
Matt Massicotte (guest) (28:13):
Okay, So first
in terms of like, struct and simple
data types that are just packaging upa bunch of data and moving them around,
Like I make so many, it's almost likea default when I make types like that.
I put sendible and hatchable, likeI add those two things to almost
everything.
Yeah.
Yeah.
So, and I think that, I thinka pretty good rule of thumb is
if it's easy to make somethingsendable, you should go for it.
(28:35):
Now classes are not easy tomake sendable, but it could be
like we talked about before,that this is a thread safe type.
It just happens
to be a class then unchecked
sendable makes a lot of sense.
Now you brought up another thing,which is I really want this type to be
sendable, but that's hard and you'reright, I'm gonna make it an actor.
Now, actors are super cool because thegood thing is they're, they are Sendible
(28:56):
and they also protect all their internalstates, and you can have all kinds of
garbage in there that is not safe atall, but the actor will keep it safe.
Leo Dion (host) (29:02):
But Leo, go ahead.
Matt Massicotte (guest) (29:04):
well there,
but they come with trade-offs.
And the trade-offs are significant.
right?
So the first one is now tothe outside world, everything
has to be asynchronous.
Their interface is now always
asynchronous.
And Yeah.
And that can be like avery profound and terrible
Leo Dion (host) (29:19):
To a code base.
But how about like,
how about to the app itself,like in performance, because
we talked about context
switching
earlier.
Like
Matt Massicotte (guest):
I wouldn't, I mean, yeah. (29:29):
undefined
Hey, That's true.
I wouldn't really give that a lotof thought unless you're very I
really don't wanna emphasize contextswitching as being a problem.
I don't think it is.
For
Leo Dion (host) (29:38):
Oh, okay.
Okay,
Matt Massicotte (guest) (29:40):
What I,
meant more was it's not so much
the performance that's the problem.
The problem is you're payingthis complexity cost for
performance you don't need.
That's really the more important thingis bouncing around to the background,
to actors to basically managelike very small amounts of states.
It's so much, first of all, simpler,but also could be more performant
to just leave that stuff on the
(30:01):
main
Leo Dion (host) (30:01):
Right, right.
Okay.
So you're basically saying.
If you need to make a class sendable,you should really consider, instead
of making an actor, make it on main
actor.
Matt Massicotte (guest):
that's, I think that's often (30:11):
undefined
exactly what people need to do.
Now, another thing, a secondpart to that is, this is getting
a little more complicated.
Leo Dion (host) (30:18):
It's perfect
for a podcast in the car.
This will be great havingthe kids in the car that
can
Matt Massicotte (guest) (30:22):
Okay, good.
Leo Dion (host) (30:23):
Yeah, no, go ahead.
Matt Massicotte (guest) (30:26):
well, I mean,
Main actors your first try, right?
As soon as you have a thing, especiallyif you find, while what I really want
to do, this happens all the time, is Ihave this one spot where I wanna read
or write this data synchronously, butI need to do that from the main thread.
That's main actor stuff.
There's nothing you can do about it.
The compiler is telling you wantthis to be on the background,
but that has a big cost and yourdesign doesn't support that cost.
(30:48):
So if you run into thatkind of situation, it's, you
really have to think hard.
Am I willing to totally redesignhow my app works to make this an
actor, or can I just make thismain actor and it's gonna be fine?
And as long as there's nolong running synchronous work,
you are gonna be fine toput that on the main actor.
Leo Dion (host) (31:04):
I'm
trying to rephrase this.
So what's the benefit of using mainactor instead of putting it as a class?
As an actor, if you don't
care that everythingis gonna be async away.
Matt Massicotte (guest) (31:15):
If you
don't care that things are gonna be
Asynchronous So there's one otherproblem with actors compared to, for
example, main actor and everything.
And that problem is not only isits interface asynchronous, but all
the inputs and outputs have to be
Leo Dion (host) (31:28):
Right.
Okay.
Matt Massicotte (guest):
Because everything has (31:30):
undefined
Leo Dion (host) (31:31):
Right, right,
Matt Massicotte (guest) (31:32):
it
is, presumably main actor,
to this actor and then back again.
So what ends up happeningis you have this problem.
You started with, oh, I justneed this class to be sendible.
I'm gonna make it an actor.
But now you fix that problem and inexchange, now all the inputs and outputs
to this type now have to be sendible.
And so usually what happensis you get down and this,
it says like never ending.
You're just chasing over and over again.
(31:53):
That type has to be sendible.
This has to be an actor.
Now, this has to be an actor.
This has to.
be an actor, and.
What you're doing is you're addingmore and more concurrency, which means
you're more and more sendible types.
And that might be what youwant to do, but I usually
just don't do
Leo Dion (host) (32:07):
a lot
of cone maintenance work.
Matt Massicotte (guest):
It's a lot of work. (32:11):
undefined
It's a lot of change.
Espec.
I mean, if you're doing something
Leo Dion (host) (32:14):
that's what
I'm
saying is like doing somethingnew, which of course is only
20% of the work out there, but
you know what I mean Yeah.
Matt Massicotte (guest) (32:21):
Yeah, I
mean I still actor is a rare thing.
I have to really be ableto justify to myself.
I actually tell a lot of people whenthey're first getting started, you
wanna make something, an actor, Iwant you to write like a little code
comment on the top of the type and say,this is an actor because, and if the
because is I needed to be sendible,that is not a good enough reason.
Leo Dion (host) (32:39):
Because if
it's synchronous, you'll never run
into the situation of, yeah.
Matt Massicotte (guest) (32:44):
Now?
Yeah, I mean, unfor, unfortunatelytoday, if you wanted to make a class,
which is very reasonable to be usedfrom a bunch of different places,
and you want it to have asynchronousmethods or even like participate in
concurrency in any way today to do thatis possible and requires a very deep
understanding of how isolation works.
but that's really unfortunate.
(33:05):
That's just
the
Leo Dion (host) (33:06):
I mean,
when you say, is that
something that we
could, is this
something that can fix it in thelanguage or is it just that's the
problem of dealing with threat
safety
Matt Massicotte (guest) (33:18):
Nope,
they're gonna fix it in the language
because the, this problem all reallycomes down to how non-isolated, and
this is a plain class, no isolationand asynchronous methods work.
and they're gonna change this.
Or at least it's being
Leo Dion (host) (33:30):
and how
are they gonna fix that?
Matt Massicotte (guest) (33:32):
Well, what
they're gonna do is for a non-isolated
type, non-isolated asynchronous methodtoday, it automatically goes to the
Leo Dion (host) (33:38):
so that's what we had
talked about earlier is that way it will
go,
if you
have a class and you're runningit in main actor, it'll stay in
main actor, and then if you run
it in something
outside of main actor, it'llstay outside of main actor.
Matt Massicotte (guest) (33:51):
So the
reason why that's so important is
that it means that you can justuse these things normally, like you
would normally, any other thing.
It makes it much more like syntacticsugar for a completion handler,
And it's it's just such an, it'ssuch an easier model for people to
understand and use for regular code.
Leo Dion (host) (34:07):
so Matt, I really
like, I'm not being sincere here.
I'm just gonna be an advocate,devil's advocate for this.
I really hate thatthey're changing that.
How can I make sure thatmy method goes into.
I guess you could just mark themethod as non-isolated, right?
I guess.
Or how would you be ableto go back to the way it is
(34:28):
now, I guess?
Matt Massicotte (guest) (34:30):
Yeah.
Very valid question.
So that's part of this proposal that is,
remember, it's not finalized yet.
But part of the proposal today, whatit looks like is if you wanna make
a method that runs on a backgroundthread, specifically, you have to
annotate it with something like,
at concurrent,
Leo Dion (host) (34:48):
Or
Matt Massicotte (guest) (34:48):
is
what's currently proposed.
Leo Dion (host) (34:49):
up with.
Matt Massicotte (guest) (34:51):
Something.
Somehow you have to indicate thisis a method that's gonna run not
Leo Dion (host) (34:55):
Is this for 6 1, 6 2?
Will this be June?
Will
this be like,
Matt Massicotte (guest) (34:59):
is.
it is not even in proposal form yet.
so I
don't
Leo Dion (host) (35:06):
Fair enough.
Matt Massicotte (guest):
But it would be cool, (35:07):
undefined
I mean, I would love to seethis for June, but it, I
don't think it'll be any sooner than
Leo Dion (host) (35:11):
so one que one thing,
I don't know if you tackled this
in a blog post or somebody did, ismain actor always the main thread.
Matt Massicotte (guest) (35:19):
Yes, I
have, sometimes said to people
before, so the confusion, there's alittle tiny bit of subtlety because
if you make a type main actor.
A lot of people remember, they'rescared of the main thread.
So they see main actor andthey think, no, I don't want
this to be on the main actor.
But the reason they're sayingthat is because there's one spot
in one method that can run somelong running synchronous code.
(35:42):
and so, but the main actoralways runs on the main thread.
But what you can, which, what youcan do is take a main actor type and
then just carve out this one littlemethod that runs on the background.
Leo Dion (host) (35:55):
Okay.
Matt Massicotte (guest) (35:56):
So
if that makes
Leo Dion (host) (35:57):
Put that
Matt Massicotte (guest) (35:57):
What I'm
saying is yes, it can say in the
same class, you can just have, youcan have everything be a main actor
type and one method of that type.
Not be main actor isolated.
today non-isolated async.
Leo Dion (host) (36:10):
So
I feel like we covered a lot.
So is there anything else weneed to cover with actors in
isolation that we haven't already?
Matt Massicotte (guest) (36:22):
I mean, it's a
big topic.
We could talk about it all day,but it seems pretty good what we've
Leo Dion (host) (36:28):
So besides
concurrency, what else do you have
to look forward to in Swift in 2025?
Matt Massicotte (guest) (36:35):
Oh,
that's a very good question.
I've been so focused on that, tobe honest, that I'm not even sure.
Um.
What else to look forward to?
Leo Dion (host) (36:44):
so we
talked about this offline,but parameter packs,
fixing those.
Matt Massicotte (guest) (36:48):
yeah,
I have used them a little bit.
And I think they're very far along,they're very usable and they added
a bunch of things in Swift 6 to makeparameter packs even more usable.
because I think before therewere some pretty rough edges.
But there are some spots definitelyif you start getting deep into
parameter packs, there are some spotswhere it doesn't quite work the way
Leo Dion (host) (37:05):
Yeah, we talked
about this with, I was trying
to set up a parameter pack and.
Posted it to the GitHub issue for Swift.
But yeah, there, I forgotwhat it was exactly, but yeah,
that, we talked about this on
NASA probably too.
But yeah, that was the onething that like, kind of stopped
me from using parameter packsfurther 'cause it didn't do
that one thing that I wanted.
Matt Massicotte (guest) (37:26):
I was
able to, for what I was trying.
I've used them one time for oneexact, exactly one project and I
was able to pull off what I wanted.
But I remember struggling alittle bit here and there, you
know, parameter pack, kind ofthe same thing as Sendible.
I.
excuse me, sending, and it kind ofreminds me of like the earlier generic
days of Swift two where you look atthe language and you write something
and you think this should work.
It totally makes sense given myunderstanding of how this all works.
(37:49):
But the compiler justisn't quite there yet.
Leo Dion (host) (37:51):
Yeah.
Anything
else you're looking forward
to
in 2025 when it, comes to Swift?
Matt Massicotte (guest) (37:57):
I mean,
I've been ignoring so much of the
I've been ignoring so much of theproposals and everything else going on
because I'm so focused on concurrency.
But personally, what I would like tosee, I mean, there were some major
improvements in Xcode in with Xcode Twothings that I loved was the support for
editor config, which is this like way of
configuring how your editor behaved.
Leo Dion (host) (38:16):
so can you do
Matt Massicotte (guest):
It's supported by. (38:17):
undefined
Leo Dion (host) (38:18):
and
then X code will read it.
Is that what it is?
Oh,
awesome.
Matt Massicotte (guest):
that's exactly it. (38:22):
undefined
That's exactly it.
And it's cool because that format issupported by basically every other
editor in the world except Xcode, butnow it's, which is really wonderful.
But the other thing that Xcodehas done, which I think is really
cool, is they've made it so that
instead of having, its like itsown internal project structure
with groups, you can just referencefolders directly, kind of like how SPM
(38:42):
works and they'll just automaticallycompile what's ever in that folder.
And that is life changing.
I mean, it's such an amazing feature.
I can't believe it took solong to arrive, but it's really
great and I just want to see
more
Leo Dion (host) (38:54):
the
file creation is a big
update in Xcode that I use a ton now.
So you can create a new empty file.
You can create a newfile from the clipboard.
You can you can select a pieceof code and say, extract this
into a new type or new file.
Like that stuff has beenamazing and I've loved that.
(39:15):
That to me has been a big advancement in
my workflow.
Matt Massicotte (guest) (39:20):
Yeah, I've
like, I've liked that a lot as well,
but what I really want to see them do isaddress some of the usability problems.
Not like with not with yourexperience using the the editor,
but with what the editor is capableor what the ID is capable of doing.
Like, SPM has some pretty biglimitations and just a lot of Problem.
For example, you can't, like, youcan't build your project if you
don't have an internet connectionunless you've pre-cash your SPM.
(39:42):
packages.
That's terrible.
These kinds of things needto be improved and I think
that SPM is so wonderful.
'cause it went so far towards being likemore easier to use open source software,
contribute to open source software,
but it just isn't quite there yet.
Where it feels like a,
Leo Dion (host) (39:56):
a package
and you don't have it,
and you don't have an
internet connection,
Matt Massicotte (guest) (40:00):
well, I
Leo Dion (host) (40:00):
right?
So you would just say you're talkingabout like the machine SPN cache.
Like why not just use that?
But if you don't
have it in that cache, so, but.
But the problem you're
saying is like, if you have itcashed globally, why is it still
trying to go out on the internet and,
Matt Massicotte (guest) (40:17):
yeah, I
mean, I think maybe a warning is fine.
Telling me I want pressuredata and I don't have it.
That's okay.
But to fail to build when you, justbecause you don't have internet
connection makes absolutely no
Leo Dion (host) (40:27):
I don't,
Huh.
That is a
Weird thing.
Or at least have a flag
like.
Matt Massicotte (guest) (40:31):
don't know
that will, I don't know that it'll
happen in all cases, but that's beena tough one that I've experienced.
And I've also found, I found a lotof other SPM related problems where
it's just, it can just be hard touse for more complex projects and I
would love to see it just bug fixes
Leo Dion (host) (40:47):
What
are some of the problems
you've run into with bigger projects?
Matt Massicotte (guest) (40:51):
I have this
like, long standing issue with an SPM
package that itself builds a c target.
And if you do that, that works fine.
unless it's part of a static libraryin an ex there's a combination of,
there's a, there's like a combinationof setup that will result in a
just not working properly without a
crazy workaround required.
Leo Dion (host) (41:10):
XE frameworks
and like.
I'll say thank
God for like ai, because likeI could not figure out how the,
well even AI got it wrong, butlike how to get to build multiple
frameworks and then package 'emand like get that all in a GitHub
workflow and all that stuff.
That's been a huge godsend for me.
(41:30):
But it's
like there's some weird stuff withXY frameworks that didn't work the
way I thought it would and yeah.
But.
Matt Massicotte (guest) (41:37):
I'm not
a huge, I mean, XI understand
why XD frameworks, were created,but I find it really annoying
Leo Dion (host) (41:42):
It's for a
React native project, so you
know, you pick your poison,
Matt Massicotte (guest) (41:46):
no.
Yes, I know.
But what I mean is XD frameworksare like solving a problem that It's
packaging up a whole bunch of differentbinaries for different architectures in
one single thing, but like the Mac OSS
executable format can do that.
Leo Dion (host) (42:00):
mean.
Matt Massicotte (guest) (42:01):
It just turns
out that like there is XD frameworks
can do a little bit more than theMako format can do, but like they
could have made the MACO format morecapable, and then XD frameworks would be
Leo Dion (host) (42:12):
Yeah.
Yeah,
Matt Massicotte (guest) (42:15):
And I'm just
disappointed.
I under probably that was a verybig technical problem to deal
with, but I'm disappointed that
Leo Dion (host) (42:20):
else you wanna
talk about before we close
out?
No, I think this has been
fantastic.
I.
So there's, we all, there's gonnabe a lot of kids in the back of
the SUV who are gonna now understandon their Christmas road trip how
to do Swift 6 thank you Matt.
Where can people find you online?
Matt Massicotte (guest) (42:37):
You can find
me while my website is maico.org.
And all the links to my,
Leo Dion (host) (42:41):
Awesome.
People can find
me on all the social medias at LeoDion ma on it's at Leo Dion at c Im.
If you're listening to this onyour podcast player, please take
some time to post a review, and ifyou're watching this on YouTube.
Please like and subscribe.
Thank you so much and I lookforward to talking to you again.
(43:03):
Bye everybody.