An exploration of Apple business news and technology. We talk about how businesses can use new technology to empower their business and employees, from Leo Dion, founder of BrightDigit.
[00:00:00] Server-Side Swift Conference
---
[00:00:00] 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.
[00:00:13] Nick Lockwood (guest): Thanks for having me.
[00:00:15] 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.
[00:00:27] Leo Dion (host): But before we jump in, I'll let you do your own introduction.
[00:00:31] 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.
[00:00:46] Nick Lockwood (guest): And some tools including Swift Format, as you mentioned.
[00:00:49] 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?
[00:01:05] 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.
[00:01:20] Nick Lockwood (guest): 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.
[00:01:31] 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.
[00:01:46] Leo Dion (host): 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.
[00:01:59] 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.
[00:02:06] 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.
[00:02:24] Leo Dion (host): 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.
[00:02:48] Leo Dion (host): So that was very cool. At least I enjoyed it a lot. And it was great to see them there.
[00:02:53] Nick Lockwood (guest): Yeah, couldn't agree more.
[00:02:55] So You Think You Know Swift?
---
[00:02:55] Leo Dion (host): So should we start by talking about linting or do you want to talk about your talk at the conference?
[00:03:02] 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.
[00:03:16] Nick Lockwood (guest): But yeah, generally the topic of the talk was Swift specifically rather than necessarily like mobile development or app development. With Swift.
[00:03:24] 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.
[00:03:42] Leo Dion (host): 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.
[00:03:59] Nick Lockwood (guest): Got a sort of go-to feel to it, right?
[00:04:01] Leo Dion (host): yeah. Yeah, exactly.
[00:04:02] 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.
[00:04:17] Nick Lockwood (guest): 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.
[00:04:29] Nick Lockwood (guest): 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.
[00:04:44] 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?
[00:04:56] Nick Lockwood (guest): yeah. Break, continue. Like all of the kind of like loop terminating commands work that way.
[00:05:01] 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?
[00:05:10] 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,
[00:05:19] Leo Dion (host): Do you remember one of 'em?
[00:05:20] 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.
[00:05:38] Nick Lockwood (guest): 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.
[00:05:53] Nick Lockwood (guest): 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.
[00:06:04] Nick Lockwood (guest): 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
[00:06:14] Nick Lockwood (guest): It's relying on a bug.
[00:06:16] 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
[00:06:26] 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.
[00:06:42] Nick Lockwood (guest): So it's it's
[00:06:43] Leo Dion (host): Codeable is a classic example
[00:06:44] 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.
[00:07:02] Nick Lockwood (guest): Yeah. I really hate writing like manual codeable implementations, not because they're particularly difficult to write or understand, but
[00:07:08] Leo Dion (host): But if it's one field, then you're like, what the hell?
[00:07:11] 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?
[00:07:19] Nick Lockwood (guest): 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.
[00:07:30] Leo Dion (host): And so then you just create a macro and spend three weeks trying to write a macro for it.
[00:07:34] 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.
[00:07:42] Leo Dion (host): Programmers love to automate, even if it makes, means it takes 'em longer.
[00:07:46] Nick Lockwood (guest): Yeah. I think there's an old joke why write in five minutes what you could spend three days automating like.
[00:07:51] Maintaining and Evolving Swift Format
---
[00:07:51] 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?
[00:08:06] Leo Dion (host): 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.
[00:08:20] 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.
[00:08:38] Nick Lockwood (guest): 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.
[00:08:52] Nick Lockwood (guest): 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.
[00:09:13] Nick Lockwood (guest): 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.
[00:09:40] Nick Lockwood (guest): 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.
[00:10:00] Nick Lockwood (guest): 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.
[00:10:19] Nick Lockwood (guest): 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.
[00:10:30] Nick Lockwood (guest): 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?
[00:10:45] Nick Lockwood (guest): 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
[00:10:54] 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?
[00:11:14] Leo Dion (host): You're using your own Lex Parser type
[00:11:17] 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
[00:11:25] Leo Dion (host): That's realms.
[00:11:27] 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.
[00:11:40] Nick Lockwood (guest): 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.
[00:12:03] Nick Lockwood (guest): 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.
[00:12:16] Nick Lockwood (guest): 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.
[00:12:34] Nick Lockwood (guest): But it also comes with some burdens. For one thing, it's a huge dependency.
[00:12:37] Leo Dion (host): I was gonna say that yes. As
[00:12:40] Nick Lockwood (guest): I have no dependencies.
[00:12:41] Leo Dion (host): you learn that quickly. How Yeah.
[00:12:44] 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.
[00:13:02] Nick Lockwood (guest): 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.
[00:13:22] Nick Lockwood (guest): 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.
[00:13:27] Leo Dion (host): So have you looked at Apple's alternative Swift Format? And what's your opinion on, obviously
[00:13:36] Nick Lockwood (guest): Yes.
[00:13:36] Leo Dion (host): Swift Syntax, so that's a lot of fun to have to get going, but like
[00:13:40] 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.
[00:13:55] Nick Lockwood (guest): 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.
[00:14:08] Nick Lockwood (guest): 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.
[00:14:30] Nick Lockwood (guest): 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?
[00:14:51] Nick Lockwood (guest): 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?
[00:15:13] Nick Lockwood (guest): 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.
[00:15:30] Nick Lockwood (guest): 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
[00:15:39] Leo Dion (host): like a little thing in the Read Me Now where it's
[00:15:41] 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
[00:15:48] Nick Lockwood (guest): I saw you, I saw your tool. Got mentioned that. I was like, no, that was Swift lit. but anyway it's fine.
[00:15:55] Nick Lockwood (guest): 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.
[00:16:11] Nick Lockwood (guest): 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
[00:16:25] Leo Dion (host): What? Let's say an example.
[00:16:27] 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.
[00:16:33] Nick Lockwood (guest): 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.
[00:16:49] Nick Lockwood (guest): One example would
[00:16:50] Leo Dion (host): closures anything with async away. Yeah.
[00:16:54] 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.
[00:17:05] Nick Lockwood (guest): 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.
[00:17:27] Nick Lockwood (guest): 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,
[00:18:00] 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.
[00:18:18] 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.
[00:18:29] 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.
[00:18:48] Leo Dion (host): 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.
[00:19:25] Leo Dion (host): And it's clear to me when I look at the history, I can see what changes are actually functional changes
[00:19:31] 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.
[00:19:43] Nick Lockwood (guest): So yeah, it's much better if there's just a tool that can do that for you.
[00:19:46] 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.
[00:20:08] Leo Dion (host): 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.
[00:20:24] Leo Dion (host): But I'm like,
[00:20:25] 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.
[00:20:40] Nick Lockwood (guest): 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.
[00:20:46] 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.
[00:21:01] 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.
[00:21:30] Nick Lockwood (guest): 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.
[00:21:44] Nick Lockwood (guest): 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.
[00:21:56] 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.
[00:22:27] Leo Dion (host): 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.
[00:22:42] Nick Lockwood (guest): You mean in terms of being accessible to beginners? Yes.
[00:22:44] Leo Dion (host): Yes. Yeah, exactly.
[00:22:45] 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.
[00:23:01] Nick Lockwood (guest): 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.
[00:23:19] Nick Lockwood (guest): 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?
[00:23:35] Nick Lockwood (guest): 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.
[00:23:46] Nick Lockwood (guest): 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
[00:23:56] Nick Lockwood (guest): It's, it, I, the language is it's just simple looking.
[00:24:00] Nick Lockwood (guest): 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.
[00:24:26] Nick Lockwood (guest): 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.
[00:24:46] Nick Lockwood (guest): 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.
[00:25:04] Nick Lockwood (guest): 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.
[00:25:22] Nick Lockwood (guest): 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.
[00:25:34] Nick Lockwood (guest): 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.
[00:25:48] Nick Lockwood (guest): I don't, I dunno what happens then.
[00:25:50] 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.
[00:26:12] Leo Dion (host): 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.
[00:26:32] Leo Dion (host): 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.
[00:26:43] 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.
[00:26:57] Nick Lockwood (guest): 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.
[00:27:14] Nick Lockwood (guest): It can't even tell you where the error was because it doesn't even know what it's dealing with anymore.
[00:27:17] 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.
[00:27:38] Leo Dion (host): 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.
[00:27:50] 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,
[00:27:58] Leo Dion (host): Oh, and it's very strong with SwiftUI, right? Because is fairly new,
[00:28:02] 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.
[00:28:06] Nick Lockwood (guest): 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
[00:28:17] Leo Dion (host): No, you never.
[00:28:18] Nick Lockwood (guest): a, yeah, it'll be a very cogent, very coherent explanation that is total nonsense.
[00:28:22] Nick Lockwood (guest): 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,
[00:28:27] 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.
[00:28:51] Leo Dion (host): '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.
[00:29:06] Leo Dion (host): 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.
[00:29:13] 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.
[00:29:30] Nick Lockwood (guest): 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
[00:29:44] 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.
[00:29:58] Nick Lockwood (guest): Yeah,
[00:29:58] Leo Dion (host): yeah, the part of the
[00:29:59] Nick Lockwood (guest): definitely be solved with tooling.
[00:30:01] 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.
[00:30:11] Leo Dion (host): 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.
[00:30:30] Leo Dion (host): You know what I mean?
[00:30:31] 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.
[00:30:46] Nick Lockwood (guest): Have you ever looked at those types? They're insane.
[00:30:49] Challenges with Swift Language Design
---
[00:30:49] Nick Lockwood (guest): 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
[00:30:56] Leo Dion (host): that's where some, some kind of tries to do that.
[00:30:59] 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.
[00:31:13] Nick Lockwood (guest): 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
[00:31:29] 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
[00:31:38] Nick Lockwood (guest): I'm not putting that in my code
[00:31:39] Nick Lockwood (guest): 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.
[00:31:51] Nick Lockwood (guest): 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.
[00:32:09] Nick Lockwood (guest): 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.
[00:32:22] Nick Lockwood (guest): 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.
[00:32:31] Leo Dion (host): Did you have any other comments about programming language design when it comes to any of the new stuff?
[00:32:37] 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.
[00:32:52] Nick Lockwood (guest): 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.
[00:33:06] Nick Lockwood (guest): 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.
[00:33:25] Nick Lockwood (guest): 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.
[00:33:41] Nick Lockwood (guest): 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.
[00:33:53] Nick Lockwood (guest): 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.
[00:34:11] Nick Lockwood (guest): But I, I
[00:34:12] 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?
[00:34:19] Nick Lockwood (guest): Yes. That was also me.
[00:34:21] 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,
[00:34:34] 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
[00:34:48] 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.
[00:34:55] 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.
[00:35:13] Nick Lockwood (guest): 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.
[00:35:29] Nick Lockwood (guest): 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.
[00:35:46] Nick Lockwood (guest): 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.
[00:35:57] Leo Dion (host): Yeah, totally. I get where you're coming from.
[00:35:59] Leo Dion (host): 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
[00:36:10] 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.
[00:36:25] Nick Lockwood (guest): 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
[00:36:31] 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
[00:36:45] 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.
[00:36:58] Nick Lockwood (guest): 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
[00:37:03] Leo Dion (host): Are you suggesting we should just have any for everything? Just put any and
[00:37:07] Nick Lockwood (guest): No, not at all.
[00:37:08] Leo Dion (host): Okay. Okay.
[00:37:09] 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.
[00:37:21] Nick Lockwood (guest): 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?
[00:37:35] Nick Lockwood (guest): 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.
[00:37:50] Nick Lockwood (guest): 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.
[00:38:07] Nick Lockwood (guest): 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
[00:38:19] Leo Dion (host): I know what
[00:38:20] Nick Lockwood (guest): approach.
[00:38:20] 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?
[00:38:27] 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.
[00:38:49] Leo Dion (host): And you're talking about an array of different e
[00:38:52] Nick Lockwood (guest): Like he hetero, heterogeneous,
[00:38:54] Leo Dion (host): right? Heterogeneous and that's what ne tries to do,
[00:38:57] 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.
[00:39:08] Nick Lockwood (guest): 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?
[00:39:21] Nick Lockwood (guest): 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.
[00:39:34] Nick Lockwood (guest): 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.
[00:39:39] Nick Lockwood (guest): 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?
[00:39:51] Nick Lockwood (guest): 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.
[00:40:06] 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.
[00:40:19] 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.
[00:40:28] Leo Dion (host): Thanks, I hate it.
[00:40:31] Nick Lockwood (guest): yeah, like I I think, sorry. No, you carry on.
[00:40:36] Leo Dion (host): I was just gonna say I was gonna, have you looked at like type throws at all?
[00:40:41] Nick Lockwood (guest): I, I have, and type throws again is something that I've wanted for a long time. And
[00:40:45] 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.
[00:41:00] 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.
[00:41:12] 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
[00:41:20] 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.
[00:41:36] Nick Lockwood (guest): 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?
[00:41:54] Nick Lockwood (guest): 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.
[00:42:10] Nick Lockwood (guest): I I'm like a fan from a distance,
[00:42:12] Leo Dion (host): Are you a fan of TypeScript? Do you think It's better than Swift?
[00:42:16] 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.
[00:42:29] Nick Lockwood (guest): 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,
[00:42:55] Nick Lockwood (guest): 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.
[00:43:02] Nick Lockwood (guest): And it's a, it's like a load of like extra boilerplate. And it's a horrible way of doing
[00:43:05] 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
[00:43:17] Nick Lockwood (guest): we, we can debate what the right way of doing this in Swift is given the constraints of Swift as the
[00:43:23] Leo Dion (host): I am being totally sarcastic though,
[00:43:25] Nick Lockwood (guest): But the the way that Typescripts would do this is you just say that this throws A or B,
[00:43:28] Leo Dion (host): right?
[00:43:29] Nick Lockwood (guest): Is the obvious right way of doing it.
[00:43:30] Nick Lockwood (guest): 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
[00:43:39] Leo Dion (host): Yeah, that's a big one.
[00:43:41] 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.
[00:43:46] Nick Lockwood (guest): 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.
[00:44:00] Nick Lockwood (guest): It would only let you use those types. You couldn't throw I dunno, an
[00:44:03] Leo Dion (host): That's
[00:44:04] Nick Lockwood (guest): there and expect it to work.
[00:44:05] 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
[00:44:10] 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
[00:44:21] Leo Dion (host): you need
[00:44:21] Nick Lockwood (guest): on themselves.
[00:44:22] 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
[00:44:32] 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.
[00:44:45] Nick Lockwood (guest): 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.
[00:45:06] Nick Lockwood (guest): 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.
[00:45:22] Leo Dion (host): I'm glad we have type throws than not having type throws, even
[00:45:25] Nick Lockwood (guest): Absolutely. It was a huge, I mean it was
[00:45:27] Leo Dion (host): you had to do a reason result every time, and I hated it. And it's
[00:45:30] 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.
[00:45:42] Nick Lockwood (guest): 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
[00:46:02] Future of Swift
---
[00:46:02] Leo Dion (host): Have you done anything with non copyable? Have you dabbled into it at all?
[00:46:07] 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.
[00:46:25] Nick Lockwood (guest): I don't think it's something you're gonna use much in an app. I've seen
[00:46:28] 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,
[00:46:39] Nick Lockwood (guest): Is a clear case. Yeah. The point is
[00:46:41] Leo Dion (host): you think they wanna get
[00:46:42] Nick Lockwood (guest): using once.
[00:46:43] Leo Dion (host): do you think they wanna get rid of classes in a way?
[00:46:47] Nick Lockwood (guest): This is an interesting question. No, so
[00:46:51] 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?
[00:47:04] 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
[00:47:19] Leo Dion (host): Right. 100%.
[00:47:21] 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.
[00:47:36] Nick Lockwood (guest): 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.
[00:47:54] Nick Lockwood (guest): 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.
[00:48:10] Nick Lockwood (guest): 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.
[00:48:26] Nick Lockwood (guest): 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.
[00:48:42] Nick Lockwood (guest): 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,
[00:48:48] Leo Dion (host): Oh, for sure. I think the backwards compatibility is a big part of that story.
[00:48:52] 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.
[00:49:08] Nick Lockwood (guest): Swift data is all about classes. They're not getting rid of them. If anything, they're doubling down on use cases for them.
[00:49:14] Leo Dion (host): Yeah. enough. Have you seen this recent proposal for vectors?
[00:49:19] Nick Lockwood (guest): I have, yes. Long overdue. I have
[00:49:21] 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.
[00:49:30] 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.
[00:49:47] Nick Lockwood (guest): 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
[00:49:56] 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.
[00:50:04] 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.
[00:50:13] Nick Lockwood (guest): 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.
[00:50:35] Nick Lockwood (guest): 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.
[00:50:50] Nick Lockwood (guest): 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.
[00:51:03] Nick Lockwood (guest): But no, the people it really pisses off are the c plus developers,
[00:51:07] Leo Dion (host): 'cause it's the
[00:51:07] 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
[00:51:17] 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.
[00:51:32] 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.
[00:51:47] Nick Lockwood (guest): 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
[00:51:54] 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,
[00:52:00] 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.
[00:52:14] Nick Lockwood (guest): Were one of the big ones.
[00:52:15] 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?
[00:52:28] Nick Lockwood (guest): That's correct. Yes. I think the mutability is like struck, like it's opt-in mutability. It also has like
[00:52:34] Leo Dion (host): That's what I
[00:52:34] Nick Lockwood (guest): ability and all of these things, right?
[00:52:36] Leo Dion (host): But basically like you can change the values, but you can't change the size,
[00:52:41] 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.
[00:52:52] 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.
[00:53:08] 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.
[00:53:29] Nick Lockwood (guest): 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.
[00:53:57] Nick Lockwood (guest): 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.
[00:54:18] Nick Lockwood (guest): 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.
[00:54:33] Nick Lockwood (guest): 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.
[00:54:48] 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?
[00:54:58] 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.
[00:55:10] Nick Lockwood (guest): 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
[00:55:17] 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
[00:55:26] 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.
[00:55:35] 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.
[00:55:47] Nick Lockwood (guest): Yeah, I really enjoyed it. Thanks for having me again.
[00:55:49] Leo Dion (host): Where could people find you online?
[00:55:51] 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.
[00:56:06] 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.
[00:56:26] Leo Dion (host): 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.