Leo Dion (host): Welcome to another episode, empower Haps.
I'm your host, Leo Dion.
Today I am joined by Nick Lockwood.
Nick, thank you so much for coming on.
Nick Lockwood (guest): Thanks for having me.
Leo Dion (host): It was so awesome to be with you in London
at Riverside Swift Conference.
I'm a big fan of yours for a long time.
Big fan of Swift Format and yeah, you did a great job at your presentation.
But before we jump in, I'll let you do your own introduction.
Nick Lockwood (guest): Okay.
My name's Nick.
I'm an iOS developer.
I have been for about 15 years now.
Prior to that I was a web dev for a few years.
I.
I've mostly worked like in, in companies.
I do a little bit of my own sort of side projects as well.
And I maintain quite a lot of open source libraries as well.
And some tools including Swift Format, as you mentioned.
Leo Dion (host): So before we get started talking about some of the
stuff we wanted to, I just wanted to see if you had any thoughts about
the conference and like how has it maybe changed your perspective on
Swift and where things are headed?
Nick Lockwood (guest): Yeah, I really enjoyed the conference actually.
I wasn't really sure what to expect beforehand.
I've never been to a sort of service side Swift conference before.
And yeah, obviously like my main focus is app development
predominantly iOS development.
So I wasn't sure how relevant it would be, but it was actually,
it was really interesting.
And I think the the sort of the real buried lead was the presence of so
many Apple people there as well.
Like the opportunity to.
Meet and talk to like folks who actually work on Swift and Apple tooling.
Leo Dion (host): And I'm like, I've been to a few conferences, but I
think this is the first one where I've seen a lot of Apple people and
also like Apple actually sponsors it besides some of the other companies
and of course Tim's company as well.
But yeah, I mean they're like actively involved and actively interested in it.
It was almost, I was telling people, especially the talks from Ben and
Tony at the beginning were very much like mini dub up talks in a lot of
ways, especially the announcement of Java and AOP was really cool.
Nick Lockwood (guest): Yeah, it absolutely had that feel to it.
And the fact that they were there in an official capacity as well, not just
hiding in the crowd and being anonymous.
Leo Dion (host): It's so like you have, you, you have a gradient
from marketing apple stuff to like developer geeky Apple stuff.
And at the very top you might have the, like announcement of a new Apple
TV show, and then you have a little bit more, is like an announcement
of a certain Apple product.
And then you get a little bit more and you have the WWDC
keynote and then a little bit geekier is the state of the union.
And this is like the last level of like geekiness Apple
announcements is like Java interop.
And I was trying to think what other talks there were, but just like for
instance, Franz talk on the width pattern with Async Away, it's like
even more, it's like way down the geeky level of apple talks and announcements.
So that was very cool.
At least I enjoyed it a lot.
And it was great to see them there.
Nick Lockwood (guest): Yeah, couldn't agree more.
Leo Dion (host): So should we start by talking about linting or do you want to
talk about your talk at the conference?
Nick Lockwood (guest): I guess we can talk a little bit about the talk.
So because, I was presenting to what I was aware was a service side, Swift
audience, and of course, like my area of expertise is really not that, like
I try to keep it as general as possible and it seems to go down pretty well.
But yeah, generally the topic of the talk was Swift specifically
rather than necessarily like mobile development or app development.
With Swift.
Leo Dion (host): I think everybody in that audience learned
something new from your talk.
It was pretty hilarious.
All the little ins and outs.
I'm just trying to think of what I picked up on.
I knew a lot of it oh, the fact that you, there's two ways of doing
an initializer with an optional I knew optional was a enum.
I didn't know that.
If you say that, it changes the format of the generated in it, which
I thought was really interesting.
And then, I don't know, there were a lot of like odds and ends.
I knew that you could do a lot with labels, but I'm always
scared of labels because I always feel like there were antiquated.
Nick Lockwood (guest): Got a sort of go-to feel to it, right?
Leo Dion (host): yeah.
Yeah, exactly.
Nick Lockwood (guest): I think that is, that, it's like when I
first encountered labels, they were in fact a substitute for go to.
I'm a super old school developer.
Like I started with BBC basic, where like every line was numbered and,
you'd go to like line 10 or whatever, and then if you inserted more code,
you had to renumber everything.
I think I first encountered labels when upgrading to like visual Basic,
and it was like, there's no line numbers, but how do you go to,
and that was the answer, right?
Yeah, I was a little surprised that labels are still around,
but they are quite useful.
And the way that they're used in Swift is very structured.
You can't like.
Break out of a function or something crazy and end up somewhere.
It, it is still following structured programming principles.
It's just sometimes it gives you that little bit of extra flexibility
when you know it's break, but Okay.
But break from where there's so many options.
Leo Dion (host): That was actually really helpful.
Yeah, I remember that from your talk.
That was really interesting.
Because I hadn't thought of that, like break from, so does that
work with continue, or would it even be applicable to continue?
Nick Lockwood (guest): yeah.
Break, continue.
Like all of the kind of like loop terminating commands work that way.
Leo Dion (host): That you talked about, what was the one thing that you're
like, people should know about it, and what was the one thing that you
say people should not know about it?
Nick Lockwood (guest): Oh gosh.
I mean there was a few things in there which are of the form.
It's really cool that you can do this, but please don't like,
like these little tricks were,
Leo Dion (host): Do you remember one of 'em?
Nick Lockwood (guest): I'm trying to remember now.
I think the thing with the optionals, so that the fact that you can, depending
on whether you use optional shorthand or like the longhand form it's, I
have used it but like whenever I use it I put a big fat comment above
it saying, this is why I'm doing this, because it's not intuitive.
It's all, and even so Swift Format has like a rule that will turn like
one type of optional into the other.
And if you start like actually treating these as having a difference in your
code, it's easily the kind of thing that somebody will just come along and say,
oh, that's not our coding convention.
I'll just switch it to the other one and then maybe have
some unexpected side effects.
So it is dangerous to play with things like this and actually I,
I caught up with one of the Apple engineers and they were laughing about
this 'cause they were saying like I don't think that was intentional.
This wasn't like, it just happens to be this way.
Like they didn't design it that way.
It's, it was somebody forgot to update a code path or something that
otherwise they'd have both worked the same way all along, most likely.
So
It's relying on a bug.
Leo Dion (host): I would almost go with the question mark
because that's the preferred way and the syntactic sugar way.
And then if you want a custom in it, then just create a
custom in it that forces you to
Nick Lockwood (guest): Yeah, for sure.
I think one of the things I've run into with Swift is that you
are really spoiled by all the code gen that it does for you.
And having to you unfortunately get these kind of like points where you
you just wanna do some little thing, you just wanna do some little bit
of customization and now you have to rewrite everything yourself.
So it's it's
Leo Dion (host): Codeable is a classic example
Nick Lockwood (guest): Codeable is and in fact this is yeah,
this is related to that.
So like sort of default initializers are something where it's yeah, you either
write nothing at all or suddenly you want it to be public and now you have
to write like, 50 lines of initializer and then you have to keep that in sync
and update it forevermore every time you add a property from now on Codeable.
Yeah.
I really hate writing like manual codeable implementations, not
because they're particularly difficult to write or understand, but
Leo Dion (host): But if it's one field, then you're like, what the hell?
Nick Lockwood (guest): Exactly.
And now I just said all of these other ones.
Yeah.
And plus, you look at one of these custom implementations and you really
have to look at this what is this doing that's different from the standard one?
And you find like just somewhere buried in deep among a hundred
properties is an optional sort of, ha hand handling it just in that
one little special case, just very slightly differently from the default.
And yeah, it's annoying.
Leo Dion (host): And so then you just create a macro and spend three
weeks trying to write a macro for it.
Nick Lockwood (guest): I think we'll get to that conversation
later, but Yeah, for sure.
This is what leads to all kinds of craziness, right?
Like people wanna avoid having to write the boilerplate so they do
something that only they can understand.
Leo Dion (host): Programmers love to automate, even if it
makes, means it takes 'em longer.
Nick Lockwood (guest): Yeah.
I think there's an old joke why write in five minutes what you could
spend three days automating like.
Leo Dion (host): Okay, so I wanted to talk about the future of Linting.
How much of a headache is it to maintain Swift Format with the fact that the
language, and that's what we want to talk about today, is how much the
language has changed over the years.
Like how much of a challenge is that?
Because if you looked at the stuff today, like one thing we'll
talk about later is type throws.
I've been really into type throws lately, and that's a big change.
And then you got async await and actors and all that, and non
ol isolate and all that stuff.
Nick Lockwood (guest): That's a really good question.
And actually it's funny because like Swift Format's quite an old tool.
Like I think I, I started work on it in 2016, something like that.
So it's it's coming up on a decade old.
And I actually did like a podcast with somebody like a couple of years
after I created it where I told them like, it was basically finished.
Like I, I considered it to be in maintenance mode and I was done
with this because there's only so much you can add to a format,
and, like it wasn't like the language was changing that much.
And I think the pace of development of Swift has actually really
accelerated in the last few years.
It felt like Swift was pretty stable for a long time between
the three to five version era.
I don't think an awful lot changed.
And maintaining Swift Format during that time was pretty like low effort.
It was pretty low maintenance.
And since async away.
It is just been an explosion of new functionality, like
new keywords in every release, like new things to think about.
And this is a great thing and I'm actually super happy that the language
is evolving and there's cool new stuff to play with, but it certainly
has made my job a little bit harder.
I think maintaining sort of format, there's kind of two pieces to it.
One is making sure it doesn't break things like, if somebody starts using
a new language feature and Swift Format doesn't understand it it, it
will do something ranging from not understanding and maybe throwing an
error to potentially like corrupting your code in some subtle way.
And that's like really bad.
And I don't want it to do that.
And I try and keep on top of that as much as possible.
Ideally, even having it updated to support new functionality
before it's out of beta so that like people will never actually
see this problem in the world.
But there's the, there's a second level of support for features,
which is with these new features comes new expectations in terms of.
Formatting.
So Swift's format's thing is that it's not just a formatter, it's opinionated.
And I try and, have an opinion about like, when there's multiple
ways to do things, I try and have an opinion about which is the
best way or, which is a good way.
And I try and add format rules that will, enforce that so that
code bases can be kept consistent.
That's the point of the tool.
And when necessary, I'll make it configurable because, not everybody
will agree about the best way, but usually people will have an opinion
on what the best way is, and I try and let them automate that rather
than having to do it manually.
So yes, there's a lot of stuff that's been added to the language where I
haven't yet really had time to form an opinion about what to do about this.
Things like typed throws.
Should I be writing a rule that will convert un typed throws to type throws?
Is that even feasible?
I don't know, like I haven't had time to look into that yet.
What I have had time to do is make sure that if you use typed throws, then you
know it's not gonna break your code.
And I think that's the bare minimum
Leo Dion (host): So yeah, I think what's the, like what's
the future, of Swift Format?
Are you intending to support all the new stuff and maintain it?
Is there some point where you're just like.
Handing it off.
How, I remember you also saying that you don't even use Swift
Syntax underneath, right?
You're using your own Lex Parser type
Nick Lockwood (guest): That's true.
Swift Format actually predates Swift Syntax by a few years.
So when I released Swift Format Swift Lint already existed.
People often confuse these, but they're entirely unrelated
Leo Dion (host): That's realms.
Nick Lockwood (guest): That's realm.
Yep.
And Swift Lint was using something called Source Kitten, which was a
wrapper that JP Simard wrote around source kit, which of course is like
the underlying compiler for Swift.
And actually much more powerful than Swift Syntax.
It can do things which Swift Syntax can't do, in which Swift Format can't
do because it actually understands the full structure of your project.
So there were rules in Swift lint for things , like removing unused imports,
I think, and stuff like inserting self and things like that, which I
have a version of in Swift Format, but it's not complete because everything
that I do is basically lexical.
Like I, I just look at the what's happening in the current file
and I can only apply rules that have that level of understanding.
I don't, for example, know the types of variables.
If things are defined in another file, I have no idea what they are.
So there, there are limits to what I can do.
And , switching over to Syntax Swift Syntax wouldn't actually help
solve that, which is why I've not had, I've not had a great deal of
compulsion to do 'cause it would be a huge refactor, a huge rewrite.
And it's not it exactly clear what it would give me.
It would potentially reduce the effort of updating to support new
features in the Swift language.
But it also comes with some burdens.
For one thing, it's a huge dependency.
Leo Dion (host): I was gonna say that yes.
As
Nick Lockwood (guest): I have no dependencies.
Leo Dion (host): you learn that quickly.
How Yeah.
Nick Lockwood (guest): Exactly.
So yeah it's a massive thing.
It would increase compile times and so on.
And like that, I need a good reason to, to switch over to it.
The other thing is that it, Swift Syntax is version specific, like it's
built for a specific version of Swift.
And one of the nice things about having my own pauser is that I
can relatively easily support.
All versions of Swift, or at least most versions of Swift, with just a single
code base, which is not, it doesn't seem to be an active goal of Swift Syntax.
So I don't anticipate that they'll be doing that.
And so yeah it has given me a lot of flexibility that like, I can release a
version of Swift Format that supports everything back to Swift three, up to
like unreleased versions of Swift with features that are still in development.
And, people can just have the one version of the tool.
They don't have to install the correct version for
their tool chain or whatever.
Leo Dion (host): So have you looked at Apple's alternative Swift Format?
And what's your opinion on, obviously
Nick Lockwood (guest): Yes.
Leo Dion (host): Swift Syntax, so that's a lot of fun to
have to get going, but like
Nick Lockwood (guest): course I'm a, I'm aware of it and I was, I've monitored
it since it would, it was its inception, there was in fact a Swift-Syntax in
the code base, unmaintained and barely functional when I wrote Swift Format.
And I assumed it wasn't going anywhere.
And for many years that assumption was true.
And then, suddenly at some point post Swift Syntax I think it was actually
a Google engineer whose name escapes me temporarily basically said, Hey
we should build a formatter on this.
And submitted that as a a, tool to Apple.
And they accepted it and it became part of their like standard set of stuff.
And even then, like it was several years before it really went anywhere,
finally, now it's being included with Xcode as like a thing that you can
actually invoke with a key combo.
And so maybe every year I'm thinking like, maybe this will be the year that
Swift Format is sherlocked for real.
Yeah, arguably maybe this is the year, like maybe it's finally
happened now that Swift Format in Swift-Format is official.
Like maybe that's it.
Maybe it's time to start winding down the project.
My, my thinking at the moment is like most, like when most people
get Sherlock by Apple you make an assessment and you're like, do I
add value above what Apple is doing?
And is that value sufficient to be worth the effort of maintaining this?
Because, a lot of the time unfortunately it's sadly the case
that people will use the worst thing just 'cause it's more convenient.
Or it's more standard or it's more out of the box.
And I think the Apple community is especially like this, like everybody
jumped on combine and forgot about like RX Swift and like the RX Swift people
were like, no, this only does 10% of the stuff that we but nobody cares, right?
Because it's the standard Apple thing.
So it's like that this is what we use now.
So there is.
There is an element of that.
I'm sure that's the case.
It's also super confusing now because now that Swift Format,
Swift-Format is a real thing, but it's called Swift Format.
I get people like giving me support requests and I'm like,
no, actually this isn't my tool.
This is Apple's one.
Or vice versa.
People post about Swift Format on social media and I'm not sure whether they're
talking about my tool or Apple's.
There's all kinds of confusion there and it's, it was bad
Leo Dion (host): like a little thing in the Read Me Now where it's
Nick Lockwood (guest): I, it hasn't quite, I actually can't remember
if I have something there or not.
Like I remember I used to have this confusion with Swift Lint, which
isn't even like the same, but people
I saw you, I saw your tool.
Got mentioned that.
I was like, no, that was Swift lit.
but anyway it's fine.
It's fine.
I think basically what I'm gonna do is wait and see I'm still working on
Swift Format, like a bunch of people are still using it and I don't, I
don't wanna give them a, I don't wanna give them a painful migration path.
And also like it, it aspires to do some things, which I don't think Apple's
Swift Format will ever try and do.
Like I said it's an opinionated tool.
I'm deliberately I have rules in there that might break things.
It's 90% okay, but 10% risk.
And I'm pretty sure Apple will never do things like that, but let a lot
of people like to use those things.
So I
Leo Dion (host): What?
Let's say an example.
Nick Lockwood (guest): As I mentioned, because I'm not compiling your project
and I don't look at anything other than the file that I'm formatting.
I have to make certain assumptions and some of them
are like very safe assumptions and some of them are less safe.
So some examples are, for example I remove self, like removing self.
Implicit self is a very common thing.
It's a rule that's on by default, but there are certain cases where
it's not actually safe to do.
One example would
Leo Dion (host): closures anything with async away.
Yeah.
Nick Lockwood (guest): So it's auto closure specifically.
So closures, it's fine.
Like I can infer whether it's safe to do there and the rule is not dumb.
It works out everything that it possibly can.
So yeah, it knows that if you use self insider closure, it's because
you have to use self inside closure.
But if you've got an auto closure at the call site, it
doesn't look any different.
Like it just looks like you're passing a parameter.
But the rule about requiring self is still there.
So the type system knows itself is needed, but there is nothing in the
syntax to tell you that it's needed.
And because I don't often, I mean I potentially, if the function was
defined in the same file, I could look it up, but it, chances are
it's defined in a different file.
And so I have no way of knowing what the type is there.
And so I just remove self anyway.
There's a mechanism where you can like register functions that, should have
self things like logging functions are typically like where people use
this and some of the standard logging stuff I've co coded in as being like,
oh yeah, this is, requires self, and then you can add your own to that list
if you want to use the rule without having to like, put exceptions at
every single place where you use it.
But it's things like that, right?
And so I don't anticipate that Apple's Swift Format will ever have a self
removal tool because it's not actually possible for them to implement it
reliably using Swift Syntax, which is the technology that they're using,
Leo Dion (host): So just that, I was just looking at it.
So Apple has 2.5 or 2,500 stars and you have almost 8,000
stars, so that's pretty good.
That's a pretty good indication of where things are right now.
I guess it'd be interesting to see how it changes over time.
Nick Lockwood (guest): Yeah, they, I think they probably got their 2000 stars
a lot quicker than I got my first 2000.
I suspect they're on a, like a sharper gradient than I am.
But yeah, we'll see.
We'll see how long before they intersect and overtake.
Leo Dion (host): I think one of the good points you've made is the
thing about linting is consistency.
Like I, I'm a big fan of linting because one of the things I wanna
look at when I go through my GI history is not white space changes.
whether somebo, somebody decided to go from tabs to spaces or spaces to tabs.
Like for me, if I can keep my code as consistent as possible and just
insert changes that are specifically functional as opposed to styling or
like formatting, then that's where like linting is really takes a big advantage.
That, and I think just like stuff like.
Making sure you have comments and certain, like documentation comments and
things like that are always helpful, but it's like always, that's why I'm a big
fan of linting and Swift formats, both in Swift lint because I just wanna make
sure every time I put something in my repo or I do a merger quest, it's always
gonna be consistent with what, whatever.
And it's clear to me when I look at the history, I can see what changes
are actually functional changes
Nick Lockwood (guest): Yeah, absolutely.
I mean it's eliminates noise and it also eliminates like wasted time during
code reviews or whatever where it's if you have a coding style, it would
be preferable if people didn't have to like manually enforce that, oh no,
you didn't use like this, whatever.
So yeah, it's much better if there's just a tool that can do that for you.
Leo Dion (host): Especially white space.
Yeah.
One of the things I like I don't know if your Swift Format does
it, but I know Swift Link does it.
It's really weird.
But like even the order of functions, I try to keep those consistent
and I know Ralph's tool, what the, what it'll do and I'm weird, but
like it'll tell me, oh, like you should put properties first and it's
second and functions and so on last.
And that's really helpful to me.
'cause like I said, like then the white, like the white noise, the noise isn't
there because the function, it's like purely functional changes whenever
I make commits to history and stuff.
And then that way everything is properly formatted in the
correct order all the time.
But I'm like,
Nick Lockwood (guest): There is some support for that,
for a code organization.
It's again, it's opinionated because this was actually contributed by
Airbnb who are big contributors and actually sponsors of Swift Format.
So a lot of the rules, a lot of the rules in there are just this
is how Airbnb likes to do it, and if you like that, then turn it on.
But I, that's not on by default.
It's something where I guess I'm not actually that strongly opinionated about
the correct order for these things.
Leo Dion (host): I am not opinionated about the correct
order, but I want it consistent.
I guess that's my thing.
It's it's not my preference to how I do it, but like at least it's
consistent every time and like then the deltas are just easier to read.
Nick Lockwood (guest): yeah, that makes sense.
I think the the difference between Swift Format and maybe a tool like Prettier
is that it's not a complete format.
So I, it's Swift is just too complex.
There's just too much to have an opinion about everything.
I don't think there is a canonical way to like format Swift code down to the
level of every character, so I do the best I can, but it's generally like
making a bunch of surgical changes to the code rather than just like taking
it down to the a ST and like fully formatting everything from scratch.
And maybe that's a stretch goal.
Maybe one day we'll have that, but I have the feeling that it's not
really possible with Swift like there's just too much variation in
the way that people like to do things.
And there's just too many things where it's just really not clear
what the right approach is there.
But as much as possible.
Yeah, I completely agree with you.
It's preferable if there's just one agreed upon way to
do things in a code base.
Maybe not universally, but in any given code base, it's better just
not to have to think about that.
Leo Dion (host): Exactly 100%.
So one of the things I wanted to talk about with you is we've talked about
it, and this has especially been the case over the last year since five,
I'd say like maybe five to five, five to six, or five to five five once we
started introducing Async a await.
And some of the stuff with like types, some in any and all that kind of stuff,
it's there's a lot of challenges that would seem for a newcomer to be able
to pick up Swift now that there's a lot of these new pieces that we've added.
Um, what have you seen?
I don't know how many new employees or new software developers you've
run into, but as far as learning Swift as the programming language
has changed and like how the design of the language has changed.
Nick Lockwood (guest): You mean in terms of being accessible to beginners?
Yes.
Leo Dion (host): Yes.
Yeah, exactly.
Nick Lockwood (guest): It's a really good question and it's one that I'm.
I feel like I'm not really qualified to answer because I I grew up with Swift,
like I was there from the beginning.
And so a lot of the things that it does that are weird, I feel like I don't
notice because, I, it's just always been that way and you get acclimatized to it.
My feeling is, I mean like Swift's bold claim is that because of this principle
of progressive disclosure, it's an easy language to learn and, maybe harder to
master, but it's, you should be able to like just dive straight in, not worry
about the things you don't need to worry about yet, write basic code and it
should be simple and easy to understand.
And I think there is a lot of truth in that.
People keep saying, oh, Swift's the new c plus.
It's got all these complicated, weird features in it.
It's but okay, yeah, sure, but how often do you actually run into
those things in your day to day?
Have you ever seen, consumable or whatever have you ever encountered
these keywords in code that you didn't like deliberately put it there?
It's just not it's not at the forefront of the language, right?
It's not like the first thing you encounter when you're
trying to write Hello world.
You don't have to worry about whether like your variable is being consumed
or not, or whether it's async.
You don't hit these things.
So I do think that the language is quite approachable and you have things like
Swift playgrounds where, maybe if the sort of editor was a little bit more
stable, I think it would actually be quite easy for, novice programmers to
It's, it, I, the language is it's just simple looking.
It's deceptive.
It's not actually that simple, but it looks simple.
And for doing simple things, I think it is pretty simple.
The fact that it keeps memory management and stuff out of the way and so on.
I think there is a danger to the sort of veneer of simplicity that,
particularly with SwiftUI, I think SwiftUI enters into the realm of
being so much more complicated than it actually looks, that it's very
easy to shoot yourself in the foot.
Even as a, I'd like to think experienced developer, I often find
with SwiftUI that I, I'll make some minor typo or something and I'll
be sitting there for 10 minutes thinking, why isn't this running?
And I'll realize that I've done something that has just hung the
compiler because it like the type confusion that I've given it is
so great that it has no idea how to even tell me what was wrong.
And like things like that are real sharp edges because, I have no idea
what a person who's not confident about coding would do in that situation.
'cause what, most of the time what I have to do is just like undo back to the
last stable point because the chances of me being able to diagnose, the missing
bracket in like a, a hundred line Swift, SwiftUI body is basically zero.
It just it feel things like that really feel like maybe they've
gone a little bit too fast.
Like they've added functionality without the sort of debugging story
really being able to keep up with it.
Things like async await don't bother me particularly, but again,
now that they've introduced all the, like the strict concurrency.
We're getting into stuff where I'm seeing very experienced
programmers throwing up their hands and going, okay, I just don't
know what I'm supposed to do here.
I just I tried to turn on like strict concurrency and it just
yeah, I just had to give up.
And that doesn't seem good.
If experienced programmers are having this issue, I've no
idea what a sort of novice is supposed to do in this situation.
Obviously what they're supposed to do is not turn on strict concurrency, but
if this is the future of the language, at some point, presumably we'll get to
a point where it's not optional anymore and everybody's expected to have it.
I don't, I dunno what happens then.
Leo Dion (host): So I think a lot of it, like the stuff
you're talking about is SwiftUI.
What I've found is type inference kind of gets in the
way of getting things to work.
Because it will just, it will try, it's hardest to figure
out what you're doing and think that you're doing it correctly.
Like I had an instance where I was adding like a toolbar button or
something and it was like I changed, all I did is change a method.
So then the method call was invalid, but I didn't realize that, and it was
like obviously giving me an error, like that's misleading, which is
what happens with us 90% of the time.
It's like I did, definitely did something wrong with the error was like
a red herring because it was trying to do type inference and thinking, oh,
like the SwiftUI view is incorrect.
And it's no, the type SwiftUI view is perfectly fine.
It's some function I was calling that doesn't exist, but it like
took me, like you said, I had to do und undo do and figure it out.
But yeah, that's.
Nick Lockwood (guest): Swift strong typing is such a useful tool.
Like when you are coding along and you change, you change the
signature of a method and it just tells you everywhere, oh, hey, you
need to add this extra parameter.
You learn to rely on that so much when you're coding and then, yeah,
in the middle of a SwiftUI body.
Doing that means that instead of it saying, oh, hey,
you missed this parameter.
Instead it's going wait, I have no idea what this thing is.
I have no idea what any of this thing is.
It.
You've got this kind of like explosion of type inference failure, where it goes
from like fully understanding everything to understanding nothing at all, and
just not being able to help in any way.
It can't even tell you where the error was because it doesn't even
know what it's dealing with anymore.
Leo Dion (host): That's where they should invest in ai.
I.
Like Xcode error messages.
I know GitHub has a thing lately where it's explain error
using a copilot or something.
And I'm like, that's 'cause I've been using the latest Mac OS
and LA the latest Objective-C.
So I've been using the new co code completion stuff in Xcode and been okay.
But like that to me is like, where you should be investing is like error
handling and like knowing the proper error that is actually going on based
on the like millions of developers who run into this all the time.
Nick Lockwood (guest): Yeah, I'm a little skeptical of these technologies.
Like I haven't used co-pilot in anger.
I'll admit.
But the problem, the problem with this sort of the
hallucination effect is like,
Leo Dion (host): Oh, and it's very strong with SwiftUI, right?
Because is fairly new,
Nick Lockwood (guest): exactly.
This is the problem, right?
So like, when it's a well established problem, sure,
it'll give you a great answer.
And like it's, it can be amazingly, like good at explaining things, but
if you are like, the second or third person to ever have encountered
this problem, if only it could just say sorry, dude, I don't know.
But
Leo Dion (host): No, you never.
Nick Lockwood (guest): a, yeah, it'll be a very cogent, very coherent
explanation that is total nonsense.
And then again, like for the novice developer who's like
relying on this to tell them what to do it's just making it worse,
Leo Dion (host): there's just so little test data out there that it's been
trained on and it's like you try to pull up like bash scripts and it's amazing.
You're trying to pull up SwiftUI, a sink await stuff.
Yeah.
You're screwed.
The one tip I would have, so a couple of tips I would have is a break
your SwiftUI stuff into smaller pieces and B like actually say what
type things are be very explicit.
'cause that's a good way of seeing, 'cause that's what it is.
It's like when you start doing the type inference, it like.
It could, it tries.
Its very best.
But once you start being very explicit about what each type is
you do colon int or colon, whatever, fu every single place you can.
That's a good way to find out what the actual error is.
And then it doesn't have to try, its hardest to do type inference.
Nick Lockwood (guest): yeah, absolutely.
I think this is, it is a problem with the language.
There's no two ways about it.
I really like type inference.
I like the aesthetics of type inference.
Like it makes it nicer to write the code, but I just don't think
they should let you infer types in situations where the compiler
can't deal with it like this.
The rules have clearly been made too lenient.
The tools are not capable of supporting the level of like type
inference that they're offering us.
And, if they had just been a little bit stricter about this and just
said, look, you have to specify the type here, we could work it
out, but the trade off is not
Leo Dion (host): Or just like it, all you have to do is in the IDE,
just put something in that says.
Explicit type and then you just have to fill in the little
template thing and like now you at least are heading somewhere.
Nick Lockwood (guest): Yeah,
Leo Dion (host): yeah, the part of the
Nick Lockwood (guest): definitely be solved with tooling.
Leo Dion (host): part of the problem is when Swift was introduced,
people were pissed about how much like types don't just like work
like they did in an Objective-C.
So I think, I feel like it's a part of that is the fact that
like in Objective-C, it didn't matter if you used an INT or
double or a whatever type.
It just could do the point or conversion for you automatically.
And like people were pissed that like in Swift you have to be very explicit about
converting your number or your string or whatever it is into the right type.
You know what I mean?
Nick Lockwood (guest): I, I think part of the problem with Swift's type
system is that like most of the time it's great, it's really easy, simple
to understand a string is a string, a number is a number or whatever, but
you do get these weird cases where if you're doing something like, I dunno,
some functional programming where you're doing like a lazy map of something.
Have you ever looked at those types?
They're insane.
Like the, the type will be like some like it'll be like a hundred
characters worth of type with like multiple nested generics in it.
There's no way you're gonna type that.
No
Leo Dion (host): that's where some, some kind of tries to do that.
Nick Lockwood (guest): Yeah.
It's some solves part of that problem, but I think it only, this is, it's
actually something I always bump into.
It's oh, I've got this horrible type, I'll use some, oh wait, that
only works for protocols, right?
It only works for some protocol, it doesn't work for some like generic type.
So Yeah, unfortunately that's not, it's not a, it's not a complete solution.
But yeah, this is the thing like, with strong types comes like ludicrous types.
And when you've, if you look at the act, the actual types of, SwiftUI
bodies with something that's got 10 sub views in it or whatever, like there's
no possible way they can expect you
Leo Dion (host): does it do the refactor.
Do the refactor in Objective-C and Objective-C.
Like actually literally types out the type and you're like, dude, come on.
Just do
Nick Lockwood (guest): I'm not putting that in my code
so yeah, I don't, I dunno what the right solution is.
I have some theories about it, but we could probably talk about language
design forever, but I generally, I prefer the sort of type script approach
where it's you, the typing is optional.
So like maybe, during development you just don't need the types and then maybe
at production time you put them in.
Whereas Swift's approaches, you always have to have the types and it
tries to make it easier by doing type inference, but it, you end up with
the worst of both worlds in some ways because it means you're having to think
about types during your development process when you don't want to.
And then also you are leaving out type information, which then has
to be inferred in your, like final build, which means your compiles will
be forever slower just because you didn't type in the type, so I don't
think it's necessarily the right trade off the way that they've done it.
I, I do I know enough about how it works to understand like
there are good reasons why it works the way that it works.
But it as a development experience, it's maybe not optimal.
Leo Dion (host): Did you have any other comments about
programming language design when it comes to any of the new stuff?
Nick Lockwood (guest): I think Swift is now feeling its age in terms of
like when you set out to design a language, it's all truth and beauty
and everything's terribly elegant.
And there's some things about Swift that are so beautiful, like the way that
they handled, mutability with struts and copy and write and everything like that.
It's so seamless and so lovely.
And I, there's no other language I've ever seen that handles this
whole mutable struts thing, the way that Swift handles it, so elegantly
where, if the SRUs are var then all its properties are var, like
this kind of thing is really nice.
Like I looked into Kotlin, which is like superficially very similar to Swift, and
it's nothing like as nice, like the way they have to like, make mutable copies
of all of their arrays everywhere.
It's just not in the same league.
But then I first started seeing like the cracks appearing in Swift when
they had this thing with slices, like array slices and substrings.
Whereas you, you remember they made this change originally.
Like a string was a string, and then they were like actually
there's a difference between a string and a string slice and we're
gonna have to make this explicit.
And it was like this doesn't feel nice anymore.
Like I, I get a range of a string and then I try and assign it to a
string and it's not the same type and I have to explicitly cast it.
And I find, felt it was a little bit downhill from there.
So yeah, it's like I almost feel Swift is.
Is it's over a decade old now.
Like maybe it's time for Swift two where they can reset
everything and do it all nicely.
Of course they won't.
You know, there's no possibility.
But we, it does feel now a little bit like, it's not the shiny
new beautiful language anymore.
It's acquiring craft that can't ever really be removed.
And it's sad, it's inevitable, but it's sad.
It would be nice if some of the kind of early mistakes could be rectified
in a way that, didn't require them to maintain source compatibility.
But I, I
Leo Dion (host): Were you the one who had the talk about why
strings don't have indexes?
Like just a simple index for character?
Nick Lockwood (guest): Yes.
That was also me.
Leo Dion (host): well obviously put that your talk, but like
that was really interesting.
Do, do you think it's a good argument to not have indexes because because
it makes it look easier than it is,
Nick Lockwood (guest): That was essentially my argument.
So it does have indexes, but the indexes aren't integer indexes basically.
And the reason for that is because computing, the difference between
indexes is a bigger o operation.
So basically the longer the distance, the longer it
Leo Dion (host): Do you think that's a good thing in API design
to be explicit about, Hey, we're gonna make this look awful because
it actually is awful underneath.
Nick Lockwood (guest): It's a compromise for sure.
So the, to turn that around, it is a very bad thing to have attractive
nuisances in your API design.
Like you do not want to have an API that looks like it's simple and
straightforward and will be quick and is actually like a foot gun.
So I think they're right to avoid that.
I think it would've been nice if they had put more effort into making it.
Easy to do the thing that you want to do and making it clear how to
do the thing that you want to do.
Because I think the problem with the Swift string design, API design is there
is probably a right way of doing things.
It's different from the C way, which is arguably the obvious way, and
it's not very clearly signposted like what you're supposed to do.
So what people re people reach for inter indexes, they don't find them.
So then they try and work with the indexes that there are and
they're horrible to work with.
And then they're like, this is horrible.
And what should they should actually be doing is something completely different,
but it's not easy to find the thing that they should be doing instead,
it's like not an obvious refactor from the code that they started with.
So maybe more work could be done there.
Leo Dion (host): Yeah, totally.
I get where you're coming from.
Swift feeling its age.
Async await was always the last thing it had to do.
Do you feel like there's more that they need to add to the language that
Nick Lockwood (guest): Yeah, it's not even apple is quite
happy to tell you like the things that, that they're missing.
So there's this thing I can't remember what it's called now with
generics basically like the generic story is not complete in Swift yet.
So there's certain kinds of generic coding that you can't do.
They've made a lot of progress there with I think there's, uh.
Parameter packs and generic parameter packs and so on, but it's still not
Leo Dion (host): parameter, brat packs are broken, by the way.
Like I, yeah, I try to do some fancy stuff with parameter packs and it's
like an actual bug in Swift, so yeah.
You can only get so far with
Nick Lockwood (guest): features, yeah, so there's a lot of stuff around that.
And I think, again, this comes back to my point before about how
I prefer the TypeScript approach.
So with Objective-C and with TypeScript, there's a bunch of things
that the type system can't really represent, but you can still do them.
It just lets you do it.
It just can't really statically enforce that you've done it.
So it's basically the failure mode in
Leo Dion (host): Are you suggesting we should just have any for everything?
Just put any and
Nick Lockwood (guest): No, not at all.
Leo Dion (host): Okay.
Okay.
Nick Lockwood (guest): What I am saying is that in Objective-C,
you can do that, right?
And it doesn't hassle you and it doesn't force you to put typecasting everywhere.
It basically just says, if you're gonna use ID for every type, I can't help you.
Like the stat, the compiler cannot help you.
You will fail at runtime.
That's on you.
But I like to have that as a get out, as an escape patch.
Right Now with Swift you can't do that because the semantics
of any are not the same.
So you, of course you can use any for every variable type, but you will have
to cast it to the thing you want it to be everywhere you pass it, right?
With objectives here, it works the other way round.
It says, ID means turn off type checking.
Just let it go, catch it at runtime.
And I think that's a nice balance because it means that you can
write like anything that can be statically type checked, you are
welcome to statically type check.
Anything that can't be statically type checked because the type
system isn't sophisticated enough.
You can have a go if you know what you're doing.
It'll work.
In Swift, if the type system can't represent it, you
are not allowed to do it.
There are perfectly valid programs that Swift will not let you write
because its type system is not sophisticated enough to handle that yet.
One day it might be sophisticated enough, but right now it isn't.
And that means that we are basically, we're limited in what we can do with
the language until the, compiler developers have figured out a way
of representing this, which is the
Leo Dion (host): I know what
Nick Lockwood (guest): approach.
Leo Dion (host): I think I know what you're talking about, but do you have
a specific like instance of something you can't do in Swift because of this?
Nick Lockwood (guest): So something that you now can do, but for a long time
you couldn't is if you had a a protocol with associated Types, A PAT, you
couldn't have an array of those, right?
You couldn't have an array of like equatable for example, or codeable
because there was no way of saying this thing conforms to a protocol
and here's an array of things that conforms to this protocol.
Leo Dion (host): And you're talking about an array of different e
Nick Lockwood (guest): Like he hetero, heterogeneous,
Leo Dion (host): right?
Heterogeneous and that's what ne tries to do,
Nick Lockwood (guest): so any has solved this problem but it, we had
to wait a long time for any, right?
Any wasn't until some late version of so a decade.
So for a decade we couldn't do that.
We couldn't have an array of, and so you had this weird compromise.
It's I'd really to add an associated type to this protocol, but if I do
that, it's gonna break all of my code.
And there is no way around it.
The only way around it would be to use any literally
any for the array of types.
And then you are into like totally un type checked like weeds, right?
So this is my point in, in something like TypeScript, you'd be able
to do this and it would be fine because it would just, the type
checking would just check as much as it could and no further.
And that's okay.
And it, and, protocols and Objective-C work in a similar sorry, not protocols.
Generics in Objective-C work in a similar way.
They'll check what they can check and if they can't check, it's fine.
Just do it anyway.
And I, that, that's what I'm saying like is maybe more optimal
from a developer experience like.
The type system in Swift often if you try and do something like this, you can
spend a lot of time like scratching your head saying, how can I represent this?
Is there some way that I can trick the type system into letting me do this?
I know it's legitimate, I know what I'm doing, but it just won't let
me do it because I can't explain to the compiler what I'm trying to do.
And like sometimes you just realize there's no way of doing it, and
you just have to give up and come up with a different approach.
Leo Dion (host): I think macros tries to do that where it basically
will create the type for you that you're trying to create.
You can kinda get away with it with macros, but of course macros are a
pain in the butt, so that's not easy.
Nick Lockwood (guest): Yeah.
Yeah.
I, again, macros were a thing that I think I wanted in Swift
for a long time, and then when they finally came, like it wasn't,
that wasn't really what I wanted.
It's thank thanks, I hate it.
Leo Dion (host): Thanks, I hate it.
Nick Lockwood (guest): yeah, like I I think, sorry.
No, you carry on.
Leo Dion (host): I was just gonna say I was gonna, have you looked
at like type throws at all?
Nick Lockwood (guest): I, I have, and type throws again is something
that I've wanted for a long time.
And
Leo Dion (host): So the one big limitation I've run into is ros.
It doesn't know how to do ros.
And that makes them like I try to use them now wherever I can, but
anytime I have to do like a, I want to do a re throw, then it's like
you can't do type throws anymore.
Nick Lockwood (guest): that's interesting.
I thought that there was, because I, the ros keyword I think is now
deprecated because supposedly type throws had a better solution for this.
But off the top of my head, I can't remember what that
solution was supposed to be.
But I thought you were supposed to be able to do that.
Leo Dion (host): Okay.
Okay.
Yeah.
Once you do a ery throw it like, doesn't it just basically you
lose the type, essentially, and it
Nick Lockwood (guest): So I think what you're supposed to do is make the.
Calling function generic on the throwing functions throws or something like that.
I could look it up, but I can't tell you off the top of my head if you
look in the original Swift evolution proposal for typed throws, I think
this is covered specifically as a case.
The, but the bigger problem I had with typed throws, which comes
down to another like language feature that I dearly wish that
Swift would have, but that the like maintainers are like absolutely like
dead set against ever adding this.
And probably it will never happen.
But basically, so you have this situation where you've got,
a function which throws two different types of error, right?
So you need the, if you want to maintain type throws the outer
function has to throw like a union of those two error types.
It could be one or the other.
And there's not really a good way of doing this in Swift TypeScript.
Again, I know I keep talking about Type, I don't even use TypeScript.
I I'm like a fan from a distance,
Leo Dion (host): Are you a fan of TypeScript?
Do you think It's better than Swift?
Nick Lockwood (guest): So I don't, for many reasons it's not better than
Swift, and I don't, I'm not a heavy enough user to actually judge whether
it's better in any way, really.
But there are things I like about, like the design of the
type system in particular.
And the thing that I like most is the way that they've handled type unions.
So in Swift, we have enums and Enums can be used as a kind of type union because
you can have different cases can have different associated like values of
different types in them, but it, that's not the right tool for a situation
where you've got function like A throws error type A and function B throws error
type B, and so function C that wraps those needs to throw error type A or B,
You'd have to create like a new type of error, which was an enum that can
wrap A or B, and then you'd have to do all the wrapping yourself manually.
And it's a, it's like a load of like extra boilerplate.
And it's a horrible way of doing
Leo Dion (host): I think you're wrong.
I think you're wrong.
I think you should write a macro that creates the enum for you,
and then you could refer to that enum that's created by the macro.
I think that's what you should be working
Nick Lockwood (guest): we, we can debate what the right way
of doing this in Swift is given the constraints of Swift as the
Leo Dion (host): I am being totally sarcastic though,
Nick Lockwood (guest): But the the way that Typescripts would do this is
you just say that this throws A or B,
Leo Dion (host): right?
Nick Lockwood (guest): Is the obvious right way of doing it.
And that way of doing type unions is it's useful in many contexts.
Like another place where Swift's type system totally lets you down is Jason.
So like when you pause Jason, it gives you a
Leo Dion (host): Yeah, that's a big one.
Nick Lockwood (guest): any anything in that dictionary can be like, it
can be a number, it can be a string, it can be like a Boolean, whatever.
Like it could be an array of any of those things.
And what type does Swift give you?
It gives you any, because there is no way of representing that type in Swift.
And the obvious way you would represent it would be a type which is a union of
int or string or a number or whatever.
And that could be strongly typed.
It would only let you use those types.
You couldn't throw I dunno, an
Leo Dion (host): That's
Nick Lockwood (guest): there and expect it to work.
Leo Dion (host): They would tell you that's what enums are for, right?
They're like enumerations and they're unions in a lot of
Nick Lockwood (guest): sure.
But they didn't use Enums.
Why didn't they use an enum?
Because it, the ergonomics that are horrible for that.
That's why they didn't, it's not actually the right tool for that job.
And so claiming that it is, but then not using it for that job is
Leo Dion (host): you need
Nick Lockwood (guest): on themselves.
Leo Dion (host): You need like a computed enum, right?
That's the way you get around it or just or I know I was being sarcastic,
but they should just have a built in macro that does that for you
Nick Lockwood (guest): Yeah.
And may, maybe that's the approach they'll eventually
take with this because they don't want to add type unions.
But I wish they'd just add type unions.
Like it would, it, would it would be so nice.
But yeah, the, this is the strength of type.
It's not so much like they're nice in the Jason Case, but
that's not the killer case.
The killer case is where you are composing these unions, like
on the fly for cases like error handling, where you don't wanna
have to define them all in advance.
So yeah that's the one kind of like thorn in type throws for me.
And this was actually part of the justification for why they didn't
have type throws originally was like, this was one of the reasons, it was
like, pretty soon if you are throwing, like you are gonna lose track of what
the type is actually supposed to be.
And you don't want to have to like, change the types throughout your whole
system just because you've added like an extra case somewhere deep in it.
So they've added type throws, but they've not fixed the
reason why they didn't have type throws in the first place.
And I do feel like this, this solution is like just sitting
there ready to be like implemented, but they're not gonna do it.
Leo Dion (host): I'm glad we have type throws than not having type throws, even
Nick Lockwood (guest): Absolutely.
It was a huge, I mean it was
Leo Dion (host): you had to do a reason result every time, and I hated it.
And it's
Nick Lockwood (guest): I was quite like, I was like an avid follower
of the evolution proposal for result when it was originally added.
And this was one of the killer use cases for it.
Like the other one, which is now obsolete, was because like at the
time we didn't have async await.
So you were using closure callbacks for handling maybe a network response
and you really wanted it to give you a result, not like an optional
error and optional data or whatever, which was a horrible ergonomic thing.
So they, results solved that problem.
But it also did give us like a glimpse at what a world where type throws
was possible would be like, because it gave us strongly typed errors
Leo Dion (host): Have you done anything with non copyable?
Have you dabbled into it at all?
Nick Lockwood (guest): I, it doesn't feel like a tool that
is, much consumable and borrowing and all of these kind of things.
It's not something I reach for very often.
Like I, I think it definitely it will have a lot of interesting use cases,
but probably they'll mostly be in like fairly low level library code.
I don't think it's something you're gonna use much in an app.
I've seen
Leo Dion (host): My, my gut feeling is that it's it's a way of, I, I
think you've hit it right on the nose.
I think it's basically like files stuff that, like literally you don't,
Nick Lockwood (guest): Is a clear case.
Yeah.
The point is
Leo Dion (host): you think they wanna get
Nick Lockwood (guest): using once.
Leo Dion (host): do you think they wanna get rid of classes in a way?
Nick Lockwood (guest): This is an interesting question.
No, so
Leo Dion (host): And what I mean by that is like either it has to be, it
has to be threat safe and be an actor, or it has to be, it has to be obstruct.
And if it has to be obstruct and it can't be copied,
then make it non copyable.
Do you know what I mean?
Nick Lockwood (guest): Yeah, for sure.
Classes are a bit of a weird thing in Swift because they,
again they cover many different roles that sort of don't feel like
they should be coupled together.
Like one of the reasons classes exist is because Objective-C compatibility was
Leo Dion (host): Right.
100%.
Nick Lockwood (guest): So if you take that away, it's does
the language need classes?
It almost feels like I, I tried, I always feel like I'm letting myself
down when I have to use a class.
It's always it's the last choice, right?
Your first choice is a structure in Enum.
And if you have to use a class, fine, you'll user a class, but
you're not gonna feel good about it.
And the thing is though, that there's no such thing as like a ref.
There's no naked reference in Swift.
We've got like in-out for passing by reference to a function.
But you can't just have an in-out property, right?
So sometimes, if you've got something like a linked list or something like
that and you need a back reference, like you have to use a class,
there's no other way of doing it.
And I often run into these situations where it's really frustrating because
the tooling around struts is so nice and the tooling around classes
is like so poor by comparison.
Like I've my, my model is like a struct and it's like self serializable,
self codeable, self equatable.
Like all of that synthesized for me.
My, my initializer is synthesized for me.
And then I suddenly realize that I need to be able to like.
Have a shared reference to this.
So like my view model can mutate the shared model or whatever, and
it's wait, if I turn this into a class, it ruins everything.
Like now I have to write my, my, my equatable implementation.
I have to write.
Like all of this has to be done manually and it's horrible.
And probably the nicest solution is to wrap the struct in a class
and just have the property exposed.
But then you've got this weird API where like you've got this level
of nesting that you don't want.
And what I really want is the language to just let me say buy ref
my struct or something like that.
But it doesn't let you do it.
Maybe they want to get rid of classes, but like they, there's a
long way to go before we can, I think,
Leo Dion (host): Oh, for sure.
I think the backwards compatibility is a big part of that story.
Nick Lockwood (guest): but e even setting that aside, like there is no
alternative like for when you have to have, when you really have to have
shared mutable state or whatever.
There is no alternative right now in the language.
And sometimes you do unfortunately, and I think again with SwiftUI and
stuff and publishers and all these kind of things, like if anything,
the usage for that has gone up.
Swift data is all about classes.
They're not getting rid of them.
If anything, they're doubling down on use cases for them.
Leo Dion (host): Yeah.
enough.
Have you seen this recent proposal for vectors?
Nick Lockwood (guest): I have, yes.
Long overdue.
I have
Leo Dion (host): Tell me the story behind, tell me the story behind
it, and first of all, how pissed you are, that it's called Vector
when you're into 3D Graphics.
Nick Lockwood (guest): Yeah.
Fair.
Okay, so there's a few different things there.
So first of all, what is it?
Basically it's, it gives you a fixed size arrays.
So there is no way of doing fixed size arrays in Swift right now, if
you import a fixed size array from C because in C, all arrays are fixed
size effectively, unless they live on unless it's a pointer to an array.
It gives you a topple, which is a, like a crazy thing because you can't
do anything with a topple, right?
You can't index it.
You can't get the nth item.
You can, you
Leo Dion (host): Like UU IDs, like UUID.
The UUID type underneath is a couple of 16 bytes and it's like, why?
Why would you do that?
Yeah.
Nick Lockwood (guest): So it's a horrible thing and it's long
overdue for them to solve this.
It was the absolute bare minimum.
Oh, what's the closest type we can map this to in Swift?
I guess we'll use a topple.
And then they never came back to it.
So yeah, it's basically useless.
If you're trying to work with C APIs that actually give you
fixed size arrays, it's hopeless.
So Vector is like the correct type for this now, and it required them
to do some infrastructure stuff.
I can't remember what it was now.
But they had to, there were some pieces missing before they could
implement this, but when they added those pieces, like they even said
at the time we are basically doing this because now we can have fixed
size arrays and now we have them.
So the name is an interesting choice.
Like as you mentioned I'm a 3D graphics person, so like you, you
might think that I was annoyed by the name, but actually I
think I'm okay with it because in fact it is literally a vector.
If you have a fixed size array of like doubles or something like.
That is the type you would want to use for a 3D graphics vector.
You'd want a, an array of, three doubles or whatever.
And Vector is the perfect name for it.
It would probably an, it would probably annoy me because then,
now what do I call my type?
But, we always have this issue in Swift.
But no, the people it really pisses off are the c plus developers,
Leo Dion (host): 'cause it's the
Nick Lockwood (guest): were, yeah, because it's a, now array means
vector and vector means array.
It's like a per, it's like perfectly, like the wrong way
around as far as they're concerned.
And I sympathize
Leo Dion (host): what was it?
What was somebody, it was like list, Swifty, I list joints, the
chat, because that's what the, that's just even more confusing.
So I think I saw the big use case is essentially for what do
you call it, for embedded Swift because of the memory constraints.
Nick Lockwood (guest): That's true.
But generally any high performance code, and particularly like stuff
like graphics code is gonna be like, excited about having this feature.
Because the big problem with Swift for performance, like writing
performant code in Swift and embedded code is performant code
almost by definition because it's usually very resource constrained.
So the big problem with Swift is it loves to allocate without telling you.
There's no way to say, don't allocate, please don't put stuff on the heap.
It just, it'll
Leo Dion (host): It's the same thing with actors and threads, right?
It's like you have no clue.
It abstracts all that away from you,
Nick Lockwood (guest): Yeah, exactly.
It's, there's a lot of abstraction going on and it's really hard to get
Swift not to allocate there's a lot of things which don't require allocation
in c where there is no way, or there's certainly, it's certainly no idiomatic
way of doing it in Swift without involving heap allocations and arrays.
Were one of the big ones.
Leo Dion (host): And so a vector is ave a vector.
I hate, I have to use this term, A vector is mutable, but
you cannot change the size.
Is that correct?
Nick Lockwood (guest): That's correct.
Yes.
I think the mutability is like struck, like it's opt-in mutability.
It also has like
Leo Dion (host): That's what I
Nick Lockwood (guest): ability and all of these things, right?
Leo Dion (host): But basically like you can change the values,
but you can't change the size,
Nick Lockwood (guest): Yeah.
So it's like an, it's like an array in every sense except that
it's, yeah, the size is fixed.
But it, it has the same value semantics as an array.
Like you can pass it around, you can make it immutable or mutable.
Leo Dion (host): So Aday, who had a really great talk at Surfside Swift,
um, he had a question on Twitter about macros that I want to close out with.
Just he wanted to know if there was, there would be any
macro you would wanna build.
Nick Lockwood (guest): I would reference Daniel Steinberg's very excellent.
Talk on this subject, which is macros are not for you.
Like they, they, macros are they're for apple to build like
infrastructure more easily.
That's how I see them.
The fact that we are able to write our own macros is a sort
of accident of the, design of the Swift language that they wanted to
make sure that the standard library in Swift is all written in Swift.
It's all dogfooding itself.
There's no magic secret behavior going on behind the scenes
or as little as possible.
As much as possible.
They want like the language runtime and everything to be written in the language
using standard language features and macros are another piece of that.
Macros allow them to implement, special functions and useful things using
like a standard built in feature of the language without having to go
in and edit the c plus code of the compiler, which I think they probably
hate doing as much as we would, but I don't think macros are intended.
You shouldn't be writing like a bunch of macros in your app.
Like your app shouldn't define like 10 new macros and write
a bunch of code using macros.
You are, it's just a way of obfuscating your code.
It's the same with custom operators, right?
Like when, when Swift came out, it's oh, you can write your own operators and
everybody's writing loads of operators and no sensible code base does that
really maybe it'll have one, or maybe you'll define a plus operator that
also works on vectors or whatever.
But like creating loads of custom macros is just a way of obfuscating your code.
And I think it's the same with macros and, unlike custom operators or property
wrappers or any of these other things, macros also come with a huge overhead in
terms of just compile time and the, just the general effort of building them.
Which is why I don't, they're not a tool that I would reach for.
It would be very much the last resort.
Like I'd probably even go to like third party code gen tools like
sorcery before I would use a macro because they're that on ergonomic
to use like in an actual code base.
Leo Dion (host): Yeah.
No, I totally get where you're coming from.
100%.
Was there anything else you wanna talk about?
Did it was what did you wanna mention about 3D Graphics before we close out?
Nick Lockwood (guest): I dunno if I had anything in particular that
I wanted to talk about with that.
It's just it's an area of interest for me.
So it's if it's something you wanted to chat about, like that's a thing
I can chat about, but I, I don't know that I necessarily, I noticed
you mentioned like the vision pro.
I don't have strong opinions about that.
There's some interesting stuff about the fact that they've basically killed scene
kit now, but I dunno if that's worth the
Leo Dion (host): we'll have to have you on again to talk about it once you spend
the, was it $3,000 on a vision pro or, I don't even know how much they are now.
Is it
Nick Lockwood (guest): It, I think it's at least that, like they're
expensive, but I guess there'll be like, maybe there'll be like
a vision pro mini for people with small heads and lower budgets.
Leo Dion (host): Heads and lower budgets.
The woman's size.
Like the watch bands.
Nick, we'll have to have you on to talk about that.
Thank you so much for coming.
This has been fantastic.
I'm really glad we finally got you on.
Nick Lockwood (guest): Yeah, I really enjoyed it.
Thanks for having me again.
Leo Dion (host): Where could people find you online?
Nick Lockwood (guest): So I have a presence on Twitter or x as
we're supposed to call it now, but I tend not to hang out there.
I'm mostly on mastered on these days.
I think that's the best place to find me.
Or, if you want to talk about my GitHub projects, then probably
GitHub is the logical place to start that conversation.
Leo Dion (host): We will put links to that in their show notes.
Thank you again, Nick.
It's fantastic.
People can find me on Twitter at Leo g Dion ma Sadan at Leo gd at c
Im bright digit.com is my company.
If you are interested in coming on the show or you are looking
for help with anything, just feel free to reach out to me.
If you're watching this on YouTube, please and subscribe,
post a review in your podcast app.
Thank you everybody.
I look forward to talking to you again.
Bye.