1
00:00:00,001 --> 00:00:07,000
It's episode 60 of the podcast, which episode 60 doesn't sound like a huge number,

2
00:00:07,000 --> 00:00:14,000
but actually 60 episodes at the pace that we record them is actually quite a long time.

3
00:00:14,000 --> 00:00:18,000
I'm not sure if that's a good thing or a bad thing.

4
00:00:18,000 --> 00:00:21,000
Well, I mean, at least we keep doing it, right?

5
00:00:21,000 --> 00:00:25,000
I mean, we've... so how many years is it actually?

6
00:00:25,000 --> 00:00:30,000
Is it... well, it's certainly two, right? It's more than two years, isn't it?

7
00:00:30,000 --> 00:00:40,000
Oh, way more than two years. It was... I think it was maybe 2021 or 2022 that we started it.

8
00:00:40,000 --> 00:00:42,000
Oh, wow, that's how long.

9
00:00:42,000 --> 00:00:48,000
I think so. I don't have a Twitter account anymore even.

10
00:00:48,000 --> 00:00:52,000
And it was the first ones I would need to look up on Twitter

11
00:00:52,000 --> 00:00:56,000
because they were only done through Twitter.

12
00:00:56,000 --> 00:01:00,000
And so I don't know whether we'll ever know what the original date was.

13
00:01:00,000 --> 00:01:05,000
I think that information may be lost to time, but it's certainly several years.

14
00:01:05,000 --> 00:01:08,000
Well, there you go. Yeah, actually, during the holiday in Germany,

15
00:01:08,000 --> 00:01:13,000
somehow we got to the topic and we talked to...

16
00:01:13,000 --> 00:01:16,000
they always ask, you know, what am I doing and stuff.

17
00:01:16,000 --> 00:01:19,000
And I said that we do our thing and that we also have a podcast.

18
00:01:19,000 --> 00:01:21,000
And they got a surprise, "What? You have a podcast?"

19
00:01:21,000 --> 00:01:26,000
And I said, "Yeah, it's actually been running for quite a while now, a couple of years."

20
00:01:26,000 --> 00:01:30,000
And that's why I wondered how actually how long it's been.

21
00:01:30,000 --> 00:01:34,000
So, yeah, it's been a while.

22
00:01:34,000 --> 00:01:39,000
It was definitely kind of...

23
00:01:39,000 --> 00:01:41,000
It was definitely not earlier than 2021

24
00:01:41,000 --> 00:01:48,000
because I remember recording the episode that we did with Simon Støvring.

25
00:01:48,000 --> 00:01:52,000
I remember where I was for that and I was in Basel in Switzerland.

26
00:01:52,000 --> 00:01:57,000
And so that dates it as after all the lockdowns finished.

27
00:01:57,000 --> 00:02:02,000
But I think it was only just after the lockdowns had finished that that was happening.

28
00:02:02,000 --> 00:02:05,000
Yeah, I mean, it definitely wasn't in 2020 because we were still...

29
00:02:05,000 --> 00:02:10,000
That was early days, which only just launched.

30
00:02:10,000 --> 00:02:16,000
And then we had the bill system and, you know, that was just...

31
00:02:16,000 --> 00:02:19,000
I think it was late '21, early '22, something like that.

32
00:02:19,000 --> 00:02:21,000
That sounds about right.

33
00:02:21,000 --> 00:02:26,000
So, 60 episodes of package talk.

34
00:02:26,000 --> 00:02:31,000
How do we fill the time, I ask myself?

35
00:02:31,000 --> 00:02:36,000
Yeah, it's funny how you think you don't really have a lot, you know, especially in summer.

36
00:02:36,000 --> 00:02:42,000
I mean, there's WWDC, obviously, but there's also this phase when everyone is just busy looking at stuff.

37
00:02:42,000 --> 00:02:49,000
And, you know, sometimes there seems to be a bit of a news gap, but there's always something, apparently.

38
00:02:49,000 --> 00:02:51,000
Yeah, there's always something.

39
00:02:51,000 --> 00:02:54,000
And today, one of the things that I want to talk about is...

40
00:02:54,000 --> 00:02:59,000
We've actually talked about this on the podcast before,

41
00:02:59,000 --> 00:03:06,000
but it was really, I think, just a passing gripe, actually, that we both...

42
00:03:06,000 --> 00:03:08,000
I know we both share this gripe.

43
00:03:08,000 --> 00:03:16,000
And that is the prevalence of packages that start with the word "Swift" in the Swift package ecosystem.

44
00:03:16,000 --> 00:03:30,000
And I did a couple of little queries on the database this week just to see what the state of the ecosystem is in terms of this problem.

45
00:03:30,000 --> 00:03:32,000
And just to be clear about the problem,

46
00:03:32,000 --> 00:03:40,000
I think both you and I believe that having the word "Swift" on the front of every Swift package is useless.

47
00:03:40,000 --> 00:03:48,000
Every search result that comes up starts with packages that begin with the word "Swift" and it is the Swift package ecosystem.

48
00:03:48,000 --> 00:03:50,000
It's not...

49
00:03:50,000 --> 00:03:56,000
Yes, there could be code from other languages inside the package, but that's not what is important with a package name.

50
00:03:56,000 --> 00:04:03,000
It doesn't really matter what the underlying code is to the consumer of the package in terms of the package name.

51
00:04:03,000 --> 00:04:06,000
So that's the issue we're talking about here.

52
00:04:06,000 --> 00:04:15,000
And I had a quick look at the database and out of the 9,300-ish packages that we have,

53
00:04:15,000 --> 00:04:20,000
8.5% of them include the word "Swift" at the beginning,

54
00:04:20,000 --> 00:04:25,000
which is almost 800 packages with the word "Swift" at the beginning.

55
00:04:25,000 --> 00:04:33,000
And I think it's not unreasonable to say that this is Apple's fault.

56
00:04:33,000 --> 00:04:35,000
[laughter]

57
00:04:35,000 --> 00:04:40,000
I think this is quite clearly Apple and the Swift language team's fault,

58
00:04:40,000 --> 00:04:48,000
because if you look at the statistics on a combination of the Apple and Swiftlang GitHub organizations,

59
00:04:48,000 --> 00:04:59,000
they have 94 total packages between them and 79 of them start with the word "Swift".

60
00:04:59,000 --> 00:05:01,000
Can I just ask...

61
00:05:01,000 --> 00:05:03,000
85% of their packages.

62
00:05:03,000 --> 00:05:11,000
Can I just ask before we go further, which part of the metadata did you check?

63
00:05:11,000 --> 00:05:14,000
Did you check the repository URL or the package name?

64
00:05:14,000 --> 00:05:15,000
I checked two things.

65
00:05:15,000 --> 00:05:16,000
Right, OK.

66
00:05:16,000 --> 00:05:17,000
I checked both.

67
00:05:17,000 --> 00:05:22,000
I checked both the repository URL and the package name.

68
00:05:22,000 --> 00:05:25,000
And if either of them were Swift, I included it.

69
00:05:25,000 --> 00:05:26,000
Right, OK.

70
00:05:26,000 --> 00:05:31,000
So it is the most sympathetic number to my argument,

71
00:05:31,000 --> 00:05:37,000
because if somebody had set the package name as something different...

72
00:05:37,000 --> 00:05:41,000
I could check this and we could follow up on it next week or next time,

73
00:05:41,000 --> 00:05:46,000
but I don't believe that the numbers would be significantly changed by that.

74
00:05:46,000 --> 00:05:48,000
But I did want to include package name in it, yeah.

75
00:05:48,000 --> 00:05:53,000
Yeah, plus I'm not even sure if it's better or worse, if it differs.

76
00:05:53,000 --> 00:06:00,000
We have cases where a package is called "Swift-Foo", but then the package name is "Foo".

77
00:06:00,000 --> 00:06:06,000
That's marginally better, because then at least what you import is closer to the package name,

78
00:06:06,000 --> 00:06:11,000
but then again the package name, I'm not even sure where stuff shows up how,

79
00:06:11,000 --> 00:06:16,000
because SwiftPM, I think, looks at the base name of the URL pretty much for resolution.

80
00:06:16,000 --> 00:06:22,000
And it's all kind of a mess, so you actually might even want to prefer to have it be the same, right?

81
00:06:22,000 --> 00:06:26,000
Swift-Foo and the package name is Swift-Foo, so at least that doesn't...

82
00:06:26,000 --> 00:06:32,000
But it's like every time I create a new package, you hit this, right,

83
00:06:32,000 --> 00:06:34,000
where you think, well, what's it going to be?

84
00:06:34,000 --> 00:06:35,000
What should it be?

85
00:06:35,000 --> 00:06:36,000
Is it...

86
00:06:36,000 --> 00:06:37,000
It's just weird.

87
00:06:37,000 --> 00:06:39,000
It's just so weird.

88
00:06:39,000 --> 00:06:41,000
I have thoughts.

89
00:06:41,000 --> 00:06:42,000
It's just...

90
00:06:42,000 --> 00:06:45,000
It's so superfluous, yeah.

91
00:06:45,000 --> 00:06:48,000
And it really does affect things like search results.

92
00:06:48,000 --> 00:06:50,000
Like everything just starts with the word "Swift".

93
00:06:50,000 --> 00:06:53,000
This is not just...

94
00:06:53,000 --> 00:07:02,000
I mean, programmers are famous for having little gripes that they kind of latch onto and never let go of.

95
00:07:02,000 --> 00:07:06,000
But I think there's actually something real to this.

96
00:07:06,000 --> 00:07:14,000
This is not just purely a little gripe, although I will admit it is also a little gripe that I have.

97
00:07:14,000 --> 00:07:16,000
But I think there is something to it.

98
00:07:16,000 --> 00:07:20,000
Anyway, I think the last time we talked about this, we had probably the same,

99
00:07:20,000 --> 00:07:24,000
roughly the same conversations we've just had right now.

100
00:07:24,000 --> 00:07:27,000
And we didn't really do anything about it.

101
00:07:27,000 --> 00:07:35,000
And the reason I'm bringing it up again is I think it might be worth actually having a conversation about this.

102
00:07:35,000 --> 00:07:47,000
Because if there's anybody in a position to at least raise this question, I think it's us managing the Swift Package Index.

103
00:07:47,000 --> 00:07:55,000
And there's not enough explanation, if any explanation, of why it is this way.

104
00:07:55,000 --> 00:07:59,000
That I think one of two things would be useful here.

105
00:07:59,000 --> 00:08:04,000
Either just to find out if there is a reason, if this is a plan,

106
00:08:04,000 --> 00:08:11,000
which it certainly seems to be a plan given the number of packages that have this that are coming out of Apple and the Swift team.

107
00:08:11,000 --> 00:08:16,000
So it seems to be intentional.

108
00:08:16,000 --> 00:08:21,000
Then understanding why it is that way would be very useful.

109
00:08:21,000 --> 00:08:29,000
And we can potentially help to get that message out there if that's the plan.

110
00:08:29,000 --> 00:08:38,000
And if it's not the plan, it gives us a chance to say, if it's not the plan, if this is just a random thing, then why are we doing it?

111
00:08:38,000 --> 00:08:43,000
I think we talked about, I think it was the last episode, we talked about the Swift ecosystem steering group.

112
00:08:43,000 --> 00:08:50,000
It struck me that this might be the perfect venue to ask this question.

113
00:08:50,000 --> 00:08:53,000
And actually, so this came up a couple of weeks ago.

114
00:08:53,000 --> 00:09:01,000
Somebody did a pull request to the Swift.org repository.

115
00:09:01,000 --> 00:09:04,000
It was about package ecosystem stuff.

116
00:09:04,000 --> 00:09:15,000
And I made a comment on that pull request saying, oh, we should explain or the Swift team should explain the naming conventions around Swift hyphen.

117
00:09:15,000 --> 00:09:19,000
And it wasn't the right venue for that conversation.

118
00:09:19,000 --> 00:09:22,000
And as soon as I typed the message, I realized it wasn't the right venue for that conversation.

119
00:09:22,000 --> 00:09:24,000
So I left, I dropped it there.

120
00:09:24,000 --> 00:09:27,000
But it did make me think, what is the right venue for that conversation?

121
00:09:27,000 --> 00:09:30,000
Because I think it's a worthwhile conversation to have.

122
00:09:30,000 --> 00:09:31,000
Yeah, absolutely.

123
00:09:31,000 --> 00:09:37,000
Yeah, and I mean, even the answer might be it's just Apple who want it that way.

124
00:09:37,000 --> 00:09:41,000
But, you know, that would be good to know because people are copying it.

125
00:09:41,000 --> 00:09:47,000
And if that's, you know, sort of a side, I think that would be a terrible side effect.

126
00:09:47,000 --> 00:09:53,000
If that's really only Apple's way of doing things, for whatever reason, it would be good to know.

127
00:09:53,000 --> 00:10:03,000
Even if the recommendation is to do a Swift dash something, I'd like to have that then as a recommendation because this currently is weird.

128
00:10:03,000 --> 00:10:11,000
Like to me, it feels like early on when Swift was the exception, like it carried information, right?

129
00:10:11,000 --> 00:10:15,000
It wasn't clear whether this was an Objective-C library or a Swift library.

130
00:10:15,000 --> 00:10:21,000
And at that point, it might have been useful to have Swift networking.

131
00:10:21,000 --> 00:10:27,000
And to be clear, you can use this with Swift directly without having to fiddle around.

132
00:10:27,000 --> 00:10:29,000
But we're long past that point, right?

133
00:10:29,000 --> 00:10:36,000
These days, you'd have Objective-C dash library to indicate that that's where it came from.

134
00:10:36,000 --> 00:10:39,000
Let's not start with that.

135
00:10:39,000 --> 00:10:41,000
I'm going to pull you back from that one right away.

136
00:10:41,000 --> 00:10:43,000
Well, I have that in my notes, right?

137
00:10:43,000 --> 00:10:50,000
If there's a Swift package with Objective-C code, it should be Swift dash Objective-C dash foo.

138
00:10:50,000 --> 00:10:58,000
But, you know, it feels like what we're doing right now is we're doing file name suffixes in Swift package prefixes.

139
00:10:58,000 --> 00:11:01,000
It's like at least stick it on the end, right?

140
00:11:01,000 --> 00:11:05,000
If there needs to be something, just stick it at the end then.

141
00:11:05,000 --> 00:11:12,000
So at least the sort order in Xcode and in other places, VS code, where you have a list of packages has some meaning.

142
00:11:12,000 --> 00:11:15,000
Because right now, it has very little meaning.

143
00:11:15,000 --> 00:11:22,000
There's packages that have, I say, proper names that are then sorted properly.

144
00:11:22,000 --> 00:11:30,000
And there's a whole host of Swift dash names that are just sticking typically towards the end of that list.

145
00:11:30,000 --> 00:11:32,000
And it's just weird.

146
00:11:32,000 --> 00:11:40,000
Plus, you just cut off a significant part of your column width with information.

147
00:11:40,000 --> 00:11:43,000
So if you stick it at the end, at least, you know, sort order is better.

148
00:11:43,000 --> 00:11:46,000
And if it's truncated towards the end, that's not a problem either.

149
00:11:46,000 --> 00:11:49,000
It's just, it just annoys me.

150
00:11:49,000 --> 00:11:52,000
You said that it was spreading, and it is spreading.

151
00:11:52,000 --> 00:11:59,000
So 79 Apple packages now result in 792 other packages.

152
00:11:59,000 --> 00:12:03,000
You know, this is not just a few packages.

153
00:12:03,000 --> 00:12:05,000
This is hundreds and hundreds of packages.

154
00:12:05,000 --> 00:12:16,000
Yes. And I think the most, I mean, like, Xcode sidebar things aside, I think that's sort of something, you know, how often do you actually look at that package list?

155
00:12:16,000 --> 00:12:17,000
I'd let that go.

156
00:12:17,000 --> 00:12:29,000
But having a package like Swift dash dependencies from point three, and I don't mean to blame point three, they're just following guidance here.

157
00:12:29,000 --> 00:12:35,000
And then doing an import dependencies is such a, it's not connected, right?

158
00:12:35,000 --> 00:12:39,000
If the package was called dependencies, and you import dependencies, that makes so much more sense.

159
00:12:39,000 --> 00:12:43,000
Like, it's, we have Swift dash foundation, and we import foundation.

160
00:12:43,000 --> 00:12:54,000
It's just, it's so weird, because normally, especially Apple are so into, you know, this seems to be named correctly, and they align stuff.

161
00:12:54,000 --> 00:12:59,000
And it's just bizarre that this is a handled so very differently.

162
00:12:59,000 --> 00:13:02,000
It's, it drives me wrong every time I see it.

163
00:13:02,000 --> 00:13:08,000
Me too. And I don't bring it up every week, but I want to.

164
00:13:08,000 --> 00:13:14,000
So here's actually, you know, bear in mind, we actually have a restraint ourselves.

165
00:13:14,000 --> 00:13:31,000
So I think, yeah, I think, I think, and I think the most important thing to say is that, is that unlike a gripe that is purely a gripe, this is a gripe with a, with a plan of action to at least get some answers to the questions, potentially, hopefully.

166
00:13:31,000 --> 00:13:33,000
Yeah, yeah, that'd be nice.

167
00:13:33,000 --> 00:13:37,000
Great. Okay, gripe over.

168
00:13:37,000 --> 00:13:52,000
The other thing we should talk about this week is there's been a change to the kind of behind the scenes processing on Swift package index that won't affect anybody with a package that is already in the index.

169
00:13:52,000 --> 00:14:07,000
It's not, this is not a change to anything important or anything like that, but it is a change to the way that you can customize your packages behavior based on whether it is the Swift package index looking at your package or Xcode looking at your package, for example.

170
00:14:07,000 --> 00:14:27,000
So this came up, well, this has come up a few times over the years, and we already had a environment variable that was being set that when our compatibility build system builds your package, we set an SPI_build environment variable.

171
00:14:27,000 --> 00:14:36,000
I think at one point it was called SPI_builder, because I think we still set both of those at the moment, but I think the official one we settled on was SPI_build.

172
00:14:36,000 --> 00:14:48,000
And then a package kind of has been struggling to get itself into the index for the last couple of weeks, which is the Swift Java package from Apple.

173
00:14:48,000 --> 00:14:50,000
There we go again with the Swift hyphen.

174
00:14:50,000 --> 00:14:55,000
I was just going to jump in.

175
00:14:55,000 --> 00:15:11,000
So yes, that couldn't go into the index because in the package manifest, the package manifest checks for the existence of a Java home environment variable, which is necessary to use Swift Java.

176
00:15:11,000 --> 00:15:19,000
But it meant that we couldn't even analyze, we couldn't even get the package name because we have to run Swift package dump package to get all that metadata.

177
00:15:19,000 --> 00:15:28,000
And we can't run that if the package manifest doesn't compile and the package manifest didn't compile if Java home wasn't set, which is not set on our analysis machines.

178
00:15:28,000 --> 00:15:46,000
So we added this week a new variable that is set both during analysis, so ingestion of your package metadata into the index, and also during the build phase, which is SPI_processing.

179
00:15:46,000 --> 00:16:01,000
And you can, so the Swift Java package now skips that check for Java home if SPI_processing is set, which means we can get into the index and it can be available for searching and all the rest of the things that we do on the Swift package index.

180
00:16:01,000 --> 00:16:02,000
Yeah, yeah, exactly.

181
00:16:02,000 --> 00:16:14,000
And we wanted to have them separate because there might be cases where you specifically want to do something only when you're in a build context, although that's probably rare, but it's also an existing variable.

182
00:16:14,000 --> 00:16:21,000
So there's no point taking that out because there's a couple of packages already using it.

183
00:16:21,000 --> 00:16:29,000
And there is just one thing, I was writing up a little bit of documentation for it yesterday, I think it was.

184
00:16:29,000 --> 00:16:43,000
And as I was writing, I thought, well, do we tell people that the purpose of this is to do small little tweaks rather than big tweaks?

185
00:16:43,000 --> 00:16:54,000
It would be possible with the Swift build or the Swift processing environment variable to give your package a full sweep of green tick marks against every platform on every Swift version.

186
00:16:54,000 --> 00:17:00,000
Because you could just skip your entire compilation, really, if it was in that environment.

187
00:17:00,000 --> 00:17:18,000
But that's not the intention of this. This is for packages that for some reason can't go into the index or can't build because of some dependency that is reasonable to require on the client, but unreasonable for us to install on all of our build machines.

188
00:17:18,000 --> 00:17:23,000
And so we're going to publicize this, obviously, in the documentation, we'll talk about it here.

189
00:17:23,000 --> 00:17:32,000
But we're not going to make a huge deal about this because we don't want people to take this as an opportunity to manipulate their compatibility results.

190
00:17:32,000 --> 00:17:39,000
Yeah, exactly. Don't know. Not much to add, really. We'll be on your case if you try and do that.

191
00:17:39,000 --> 00:17:53,000
I think the truth of it is that we probably wouldn't notice. But I know we are. We're checking every result. We're checking every result. So beware.

192
00:17:53,000 --> 00:17:59,000
Do we have any other news or other items to talk about before we get into package recommendations?

193
00:17:59,000 --> 00:18:11,000
We could very briefly talk about something I noticed this last week, and it was a social media post by Joe Groff from the Apple Swift team.

194
00:18:11,000 --> 00:18:22,000
And he mentioned a Rust paper or a paper based on Rust or using Rust to implement something that I found quite interesting.

195
00:18:22,000 --> 00:18:29,000
It's a tool called Paralegal, which is a static analysis tool for privacy bugs.

196
00:18:29,000 --> 00:18:34,000
And I thought that was interesting for a number of reasons, despite it being Rust.

197
00:18:34,000 --> 00:18:39,000
First and foremost, privacy issues can be quite significant issues.

198
00:18:39,000 --> 00:18:51,000
I mean, obviously, not of the order of crashes like in concurrency land or stuff like the boring that we've seen now, all the other affordances that Swift brings.

199
00:18:51,000 --> 00:18:59,000
Obviously, not as important as package naming either. I mean, that's the real issue that we're dealing with today, right?

200
00:18:59,000 --> 00:19:07,000
No way. But if you think of it in terms of GDPR, for instance, there are requirements on you handling data.

201
00:19:07,000 --> 00:19:14,000
Like there's a requirement for you to offer data deletion when a user requests some account deletion.

202
00:19:14,000 --> 00:19:24,000
You have to delete all associated data. And, you know, the enforcement is lacking a bit in the EU regarding that.

203
00:19:24,000 --> 00:19:28,000
But that's probably not something you want to count on forever.

204
00:19:28,000 --> 00:19:39,000
So a tool like this might be really nice where you can use a static analysis tool to tell you whether you've actually implemented that correctly.

205
00:19:39,000 --> 00:19:56,000
And the other thing is these rules. And I've actually been in a project in the past with just as GDPR came into effect where we had an online site and there was interaction with a legal team that were quite eager to ensure that we were compliant.

206
00:19:56,000 --> 00:20:08,000
And the difficulty often is that these rules are being managed by one team, like a legal team that has no engineering experience and are implemented by an engineering team that doesn't have any legal experience.

207
00:20:08,000 --> 00:20:20,000
And also often like aren't as keen on, you know, dotting the I's and crossing the T's on all of these seemingly arbitrary rules, perhaps.

208
00:20:20,000 --> 00:20:25,000
So you have a bit of a disconnect between the two teams managing this.

209
00:20:25,000 --> 00:20:39,000
And also the way this often happens is you get the rules and then you implement it once and then over time that can drift right because they have nothing that constantly checks that the rules are still in effect.

210
00:20:39,000 --> 00:20:50,000
So the way typically these are checked over time is that you have audits, you know, once a year or every two years or so that check the code base, whether you are compliant.

211
00:20:50,000 --> 00:20:59,000
There are also some specialized tools that do this, but they're often domain specific like targeting SQL or database tables and stuff.

212
00:20:59,000 --> 00:21:09,000
And so whenever you have a system that is composed of different parts and, you know, honestly, which system isn't right, you'll only have coverage of one part of the system.

213
00:21:09,000 --> 00:21:12,000
You have nothing that has a holistic view of everything.

214
00:21:12,000 --> 00:21:14,000
How is that being dealt with?

215
00:21:14,000 --> 00:21:24,000
So what this paralegal thing does, it uses Rust's, like something similar to Rust's borrowing mechanism.

216
00:21:24,000 --> 00:21:30,000
It has annotations where you annotate your code with stuff that is privacy relevant, like data.

217
00:21:30,000 --> 00:21:32,000
This is privacy relevant data.

218
00:21:32,000 --> 00:21:39,000
And then you can annotate other parts that handle the data, like, for instance, deletion, a function that deletes data.

219
00:21:39,000 --> 00:21:47,000
And then the static analysis tool would ensure that if you have a rule, this must be deleted under certain conditions.

220
00:21:47,000 --> 00:22:00,000
It would actually ensure that all the data is marked as private is actually leading to this to the sink where it's gone right to this function where it's being deleted and completely deleted.

221
00:22:00,000 --> 00:22:03,000
And it can do that in real time.

222
00:22:03,000 --> 00:22:12,000
So once you have specified the rules and instrumented your code, the instrumentations live alongside your code.

223
00:22:12,000 --> 00:22:15,000
So it's, you know, it's not, they're not easily stripped.

224
00:22:15,000 --> 00:22:19,000
They'll be there as semantic annotations.

225
00:22:19,000 --> 00:22:22,000
And you always have this almost like a unit test.

226
00:22:22,000 --> 00:22:26,000
You always have this being checked as you work on the code base.

227
00:22:26,000 --> 00:22:35,000
But the other advantage is that the rules are actually written in sort of a high level language that can be managed by a legal team.

228
00:22:35,000 --> 00:22:42,000
They're intended to be managed by a team that is in this different domain that deals with the legal side of things.

229
00:22:42,000 --> 00:22:53,000
And sort of the machine then maps this to the static analyzer or rather the static analyzer takes these rules as written and checks the code base against them.

230
00:22:53,000 --> 00:22:58,000
And I find that really interesting that this is actually possible, that it exists.

231
00:22:58,000 --> 00:23:04,000
And obviously Swift has many similarities to Rust, right?

232
00:23:04,000 --> 00:23:09,000
There is borrowing now in, I'm not sure which Swift version that landed in.

233
00:23:09,000 --> 00:23:12,000
Was it 6.1 or was it upcoming in 6.2?

234
00:23:12,000 --> 00:23:19,000
I don't know, but I know that it sort of has that capability now.

235
00:23:19,000 --> 00:23:38,000
And given how privacy conscious Apple are, I wonder if that is, and obviously Joe Groff on the Swift compiler team, obviously might be interested in that for that reason as well.

236
00:23:38,000 --> 00:23:45,000
I wonder if that's going to be one of the future things, shipping at some point in Swift to allow that.

237
00:23:45,000 --> 00:23:54,000
One thing I liked about this was at first when I skimmed, I haven't read the full paper, I'll be upfront about that.

238
00:23:54,000 --> 00:23:59,000
But I did skim it and in today's world, surely that's enough, right?

239
00:23:59,000 --> 00:24:10,000
One thing I thought was unusual about this when I first looked at it was, I thought, well, why are you doing this at the level of the compiler, at the language level?

240
00:24:10,000 --> 00:24:13,000
This feels like a higher level task actually.

241
00:24:13,000 --> 00:24:21,000
But the more I thought about it, the more I thought that this is absolutely, either here or the database are the places to do this.

242
00:24:21,000 --> 00:24:31,000
Because as soon as you move up in the code towards the user interface, you have to remember to check these things.

243
00:24:31,000 --> 00:24:46,000
Whereas if it's at the point of data storage or the source of truth of data, to have that metadata around at that point is the way to keep this consistent and not have to remember to check it before you do something with it.

244
00:24:46,000 --> 00:24:52,000
So the more I thought about it, the more I thought it was a sensible way to approach it.

245
00:24:52,000 --> 00:25:03,000
Yeah, and I mean, we've seen this time and again, right, with several things in Swift, that stuff is being pushed to the type system, right?

246
00:25:03,000 --> 00:25:08,000
The concurrency and concurrent access is all actors and stuff.

247
00:25:08,000 --> 00:25:15,000
That's all type system mechanics to ensure that stuff is working correctly.

248
00:25:15,000 --> 00:25:17,000
Like memory safety is all type system.

249
00:25:17,000 --> 00:25:20,000
Borrowing is handled by the type system.

250
00:25:20,000 --> 00:25:23,000
So it kind of makes sense to leverage that again, right?

251
00:25:23,000 --> 00:25:29,000
Because privacy relevant data is sort of a specific type of data.

252
00:25:29,000 --> 00:25:39,000
Why not then let the compiler be aware of that and carry it through the system and sort of make that kind of data almost like a...

253
00:25:39,000 --> 00:25:42,000
In my mind, I haven't read the paper in detail either.

254
00:25:42,000 --> 00:25:44,000
I mean, it's beyond me.

255
00:25:44,000 --> 00:25:56,000
But it sort of made sense that if you think of privacy relevant data as sort of a special kind of memory, then borrowing is with the sources and sinks it manages.

256
00:25:56,000 --> 00:26:00,000
It's sort of like handling that special kind of memory with a special kind of borrowing mechanism.

257
00:26:00,000 --> 00:26:04,000
It makes sense that this is kind of similar, right?

258
00:26:04,000 --> 00:26:06,000
I'm surprised that it does work.

259
00:26:06,000 --> 00:26:08,000
And obviously, you need to annotate stuff, right?

260
00:26:08,000 --> 00:26:14,000
You will need to tell the system, well, this is a function that deletes data.

261
00:26:14,000 --> 00:26:20,000
And obviously, at some point, you'll have to ensure that stuff works as expected.

262
00:26:20,000 --> 00:26:24,000
But there's a lot beyond that, that the thing can check that you don't forget.

263
00:26:24,000 --> 00:26:32,000
Like there's no point in having a function that deletes data if you haven't given it all the data that it needs to delete or if you forget to call it.

264
00:26:32,000 --> 00:26:39,000
And that sort of stuff, even though it might seem trivial, is stuff that that's how stuff happens, right?

265
00:26:39,000 --> 00:26:46,000
These links break as you maintain a system over time and stuff happens to not be called anymore.

266
00:26:46,000 --> 00:26:50,000
And especially deletion isn't typically something that's in the hot path, right?

267
00:26:50,000 --> 00:26:52,000
You don't notice that stuff hangs around.

268
00:26:52,000 --> 00:26:54,000
You notice when stuff's gone, right?

269
00:26:54,000 --> 00:27:00,000
When you do your testing, it's very easy to overlook that you've left something lying around.

270
00:27:00,000 --> 00:27:07,000
Because it's, you know, unless you look at, you know, the storage you're taking up, you hardly ever notice that sort of thing.

271
00:27:07,000 --> 00:27:10,000
So it kind of made sense to me.

272
00:27:10,000 --> 00:27:19,000
And I'm curious if we might see that in the, well, it's probably in the far future of Swift.

273
00:27:19,000 --> 00:27:23,000
Swift 26, yeah.

274
00:27:23,000 --> 00:27:32,000
I will include a link in the show notes to that article if any of you also don't want to read the paper.

275
00:27:32,000 --> 00:27:38,000
Or if any of you want to read it and then come back at us and explain how we got it wrong.

276
00:27:38,000 --> 00:27:42,000
Explain why we're wrong, yeah, exactly.

277
00:27:42,000 --> 00:27:46,000
Let's go straight into some package talk then.

278
00:27:46,000 --> 00:27:56,000
I'll kick us off this week with my first pick is a package called Cadova from Thomas Franzen.

279
00:27:56,000 --> 00:28:02,000
And this is actually not a super old, sorry, a super new package.

280
00:28:02,000 --> 00:28:05,000
This has been in development for four years.

281
00:28:05,000 --> 00:28:09,000
But it's the first time I came across it this week.

282
00:28:09,000 --> 00:28:11,000
And it's a kind of interesting concept.

283
00:28:11,000 --> 00:28:18,000
So the way that I would describe it is Swift UI for 3D printing.

284
00:28:18,000 --> 00:28:27,000
You get a kind of result builder style interface to building 3D models.

285
00:28:27,000 --> 00:28:34,000
So, for example, one of the examples in the getting started guide is to say,

286
00:28:34,000 --> 00:28:40,000
make a box of size 10, 10, 5 in whatever units it uses.

287
00:28:40,000 --> 00:28:45,000
I'm not actually sure what the units are, but they are not specified in the example.

288
00:28:45,000 --> 00:28:55,000
So 10, 10, 5 box, subtracting a sphere of diameter 10, translated on the Z axis by 5.

289
00:28:55,000 --> 00:29:04,000
And so what you get there is a cuboid, which is an elongated rectangle.

290
00:29:04,000 --> 00:29:07,000
Is that a cuboid? I think it is.

291
00:29:07,000 --> 00:29:12,000
With a chunk taken out of the side in the shape of a sphere.

292
00:29:12,000 --> 00:29:17,000
So a sphere intersecting the cuboid, then subtracted.

293
00:29:17,000 --> 00:29:26,000
And I'm guessing you could make reasonably complicated designs like this.

294
00:29:26,000 --> 00:29:34,000
But that you could store the kind of the template for those 3D printing files in code rather than...

295
00:29:34,000 --> 00:29:37,000
Well, actually it does. It generates what's called a 3MF file,

296
00:29:37,000 --> 00:29:41,000
which I presume is the file that you give to your 3D printer.

297
00:29:41,000 --> 00:29:44,000
But I thought it was a nice way to think about this problem.

298
00:29:44,000 --> 00:29:46,000
Interesting. Okay.

299
00:29:46,000 --> 00:29:51,000
So that's probably something if you have lots of stuff that is kind of similar that you want to generate, right?

300
00:29:51,000 --> 00:29:55,000
Because, you know, in general, you'd probably want to rather...

301
00:29:55,000 --> 00:29:56,000
Yeah, you could.

302
00:29:56,000 --> 00:30:00,000
You can't draw it, but I guess that makes sense if you automate stuff.

303
00:30:00,000 --> 00:30:08,000
If you were iterating over something and, yeah, or taking a subtraction out of several pieces

304
00:30:08,000 --> 00:30:11,000
and then splitting them up into... I don't know. I don't do a lot of 3D printing.

305
00:30:11,000 --> 00:30:13,000
But I thought it was interesting.

306
00:30:13,000 --> 00:30:20,000
The README file for this is okay, but it's not great in that it doesn't actually give any kind of examples.

307
00:30:20,000 --> 00:30:26,000
But if you... In the first section of the README file, there was a link to a Getting Started guide,

308
00:30:26,000 --> 00:30:38,000
which is a markdown file on GitHub that gives you a nice example and a screenshot of the resulting shape.

309
00:30:38,000 --> 00:30:42,000
So it's obviously difficult to talk about this kind of stuff, 3D visualizations,

310
00:30:42,000 --> 00:30:45,000
but go and have a look at the Getting Started guide.

311
00:30:45,000 --> 00:30:52,000
My first pick is called Swift QC by Sheldon Aristide.

312
00:30:52,000 --> 00:30:59,000
And QC is not Queen's Council. This is based on Haskell's QuickCheck.

313
00:30:59,000 --> 00:31:03,000
So it's a testing library. That's what Haskell's QuickCheck is.

314
00:31:03,000 --> 00:31:10,000
And the point is it's so-called property-based testing.

315
00:31:10,000 --> 00:31:20,000
So what that means is effectively you don't write an expect expression where you have sort of static content on either side.

316
00:31:20,000 --> 00:31:25,000
You sort of write down a... You have a closure where you take arguments.

317
00:31:25,000 --> 00:31:28,000
And I'd probably best just give an example.

318
00:31:28,000 --> 00:31:31,000
So you have a forAll function, and it takes this closure.

319
00:31:31,000 --> 00:31:38,000
And for instance, you'll say you have two strings, and you say string1 plus string2 is a combined string.

320
00:31:38,000 --> 00:31:45,000
And then your expectation is that the count, for instance, of the combined string has to be the sum of the counts of the individual strings.

321
00:31:45,000 --> 00:31:56,000
So this would be a test that ensures when you concatenate strings that the length of the combined string is the sum of the individual strings.

322
00:31:56,000 --> 00:32:05,000
And obviously, this is a trivial example, but there might be parts of your system where you want to ensure that not just for some numbers that you pick at the start,

323
00:32:05,000 --> 00:32:11,000
that might be sort of magic numbers, or you might hit some magic numbers, and then for other numbers it might fail.

324
00:32:11,000 --> 00:32:14,000
Or inputs, I should say, not numbers.

325
00:32:14,000 --> 00:32:22,000
And this forAll will actually take types that it then picks values from to run, like over a...

326
00:32:22,000 --> 00:32:32,000
I'm not even sure... I think you can specify the number of iterations, but it'll pick values and then ensure that the closure is true,

327
00:32:32,000 --> 00:32:36,000
or the expectation holds for the values that it puts in.

328
00:32:36,000 --> 00:32:39,000
So it'll do that for a range.

329
00:32:39,000 --> 00:32:49,000
And the interesting bit, on top of just doing this, is that if it finds a violation of that expectation, it'll actually...

330
00:32:49,000 --> 00:32:58,000
This is called shrinking. It'll shrink the inputs to find the minimal inputs that also fail and give you that result.

331
00:32:58,000 --> 00:33:07,000
So you can imagine you might have very complex inputs, and in order to make debugging easy, it's always helpful to have a reduced example.

332
00:33:07,000 --> 00:33:10,000
And it'll do that automatically.

333
00:33:10,000 --> 00:33:23,000
And this comes with lots of implementations for existing types, like the standard library types, like strings, ints, dictionaries, arrays, and all that,

334
00:33:23,000 --> 00:33:27,000
have all this already provided.

335
00:33:27,000 --> 00:33:31,000
Like there's an arbitrary protocol, it's called arbitrary.

336
00:33:31,000 --> 00:33:42,000
If you implement that in your types, you can also allow them to be used as inputs to do this picking of inputs.

337
00:33:42,000 --> 00:33:50,000
And there's another protocol that you can implement, the shrinking, so that you can actually, for your custom type, can define how would you actually minimize your type.

338
00:33:50,000 --> 00:33:59,000
Because, as you can imagine, depending on the type, it might be very different on how you actually make it "smaller".

339
00:33:59,000 --> 00:34:06,000
So yeah, I found that really interesting, and I know that this is a big thing in Haskell to do this kind of checking,

340
00:34:06,000 --> 00:34:11,000
because the functional languages often are... The thing that you check is your functional implementation,

341
00:34:11,000 --> 00:34:24,000
and then it's kind of more common to vary the inputs and throw a range of inputs at the function and let this find edge cases and stuff.

342
00:34:24,000 --> 00:34:31,000
The other thing to say is, this works, so this exists both for XCTest and SwiftTesting,

343
00:34:31,000 --> 00:34:38,000
but it's actually one of those libraries where SwiftTesting has a quite nicer implementation,

344
00:34:38,000 --> 00:34:45,000
because the error reporting is improved in the sense that it'll only...

345
00:34:45,000 --> 00:34:57,000
Once it hits an error, like a failure, and it starts the shrinking, it will not show all the errors that it sees along the way,

346
00:34:57,000 --> 00:35:01,000
it'll only report the final minimal result that it found.

347
00:35:01,000 --> 00:35:05,000
And in XCTest that's not possible, but with SwiftTesting that's actually possible,

348
00:35:05,000 --> 00:35:11,000
because it can mark these errors specifically so they don't clutter your error reporting,

349
00:35:11,000 --> 00:35:15,000
and you only get the final nice result at the end.

350
00:35:15,000 --> 00:35:24,000
So there you go, a nice testing library, and one that actually makes use of the new SwiftTesting affordances to make it nicer.

351
00:35:24,000 --> 00:35:36,000
Fantastic. My next package for this episode is called Email Validator by David Sherlock.

352
00:35:36,000 --> 00:35:39,000
Actually I'm not quite sure if it's by David Sherlock or David Michael.

353
00:35:39,000 --> 00:35:44,000
The author information says David Sherlock, the GitHub author says David Michael,

354
00:35:44,000 --> 00:35:50,000
so I'm not 100% sure on the author name there.

355
00:35:50,000 --> 00:35:56,000
This does pretty much what you would expect it to do.

356
00:35:56,000 --> 00:36:02,000
Hands up if you have ever validated an email address with a regular expression.

357
00:36:02,000 --> 00:36:06,000
I know I'm putting my hand in the air right now and I'm sure Sven is as well.

358
00:36:06,000 --> 00:36:09,000
How hard can it be?

359
00:36:09,000 --> 00:36:13,000
How hard can it be, right? How hard can it be?

360
00:36:13,000 --> 00:36:17,000
This does not use, well actually I'm not sure what it uses behind the scenes,

361
00:36:17,000 --> 00:36:23,000
but what it says is it says it uses WordPress's battle-tested validation logic,

362
00:36:23,000 --> 00:36:26,000
which I'm sure there are probably regular expressions in that,

363
00:36:26,000 --> 00:36:32,000
but it's certainly more than a simple single regular expression.

364
00:36:32,000 --> 00:36:38,000
It validates based on the RFCs, first of all.

365
00:36:38,000 --> 00:36:42,000
It has zero dependencies. It has provider detection,

366
00:36:42,000 --> 00:36:47,000
so recognizes major email providers and can tell you whether an email address

367
00:36:47,000 --> 00:36:52,000
is likely a personal or a work email address.

368
00:36:52,000 --> 00:36:57,000
It also deals with all of the edge cases of email addresses,

369
00:36:57,000 --> 00:37:01,000
like for example there's characters that you might not think would be available

370
00:37:01,000 --> 00:37:05,000
to an email address that are perfectly valid within an email address.

371
00:37:05,000 --> 00:37:14,000
It also does normalization of emails, so lower casing basically of email addresses.

372
00:37:14,000 --> 00:37:19,000
Actually it seems to be slightly more subtle than that.

373
00:37:19,000 --> 00:37:25,000
It says it's a lower case domain, so it keeps the username capitalized as the input,

374
00:37:25,000 --> 00:37:29,000
but the domain gets lower cased.

375
00:37:29,000 --> 00:37:35,000
It just copes with all these different situations where you might make a mistake

376
00:37:35,000 --> 00:37:39,000
when handling email addresses, which is something that most applications

377
00:37:39,000 --> 00:37:42,000
need to do at some point.

378
00:37:42,000 --> 00:37:45,000
I thought that was just a really nice little package.

379
00:37:45,000 --> 00:37:49,000
It's only nine days old, so it's a fairly new package, this one.

380
00:37:49,000 --> 00:37:54,000
Actually currently, I should mention that it does not have an open source license.

381
00:37:54,000 --> 00:37:58,000
It has no license, so you should not use this at the moment,

382
00:37:58,000 --> 00:38:00,000
but I'm guessing given that it's only nine days over,

383
00:38:00,000 --> 00:38:04,000
that is an omission rather than anything intentional.

384
00:38:04,000 --> 00:38:09,000
Hopefully David will get that sorted out and put a license on it,

385
00:38:09,000 --> 00:38:13,000
whatever the license he intended it to be under,

386
00:38:13,000 --> 00:38:17,000
that he should make that explicit in the repository.

387
00:38:17,000 --> 00:38:23,000
Nice. Yeah, that sounds like a great package because checking email addresses

388
00:38:23,000 --> 00:38:26,000
for validity must be a nightmare, right?

389
00:38:26,000 --> 00:38:31,000
Because also even providers implement this differently.

390
00:38:31,000 --> 00:38:39,000
I'm not sure if it checks any of that, but you can add the plus something at the end.

391
00:38:39,000 --> 00:38:42,000
Not all providers allow that. I think that's RFC compliant. I'm not sure.

392
00:38:42,000 --> 00:38:45,000
It's just a minefield.

393
00:38:45,000 --> 00:38:50,000
Plus is a valid character in any email address.

394
00:38:50,000 --> 00:38:57,000
It's just that some providers then choose to implement that to mean a filter

395
00:38:57,000 --> 00:39:00,000
or a filterable thing inside the mailbox.

396
00:39:00,000 --> 00:39:06,000
But I think the key thing here is that if anybody can validate an email address,

397
00:39:06,000 --> 00:39:09,000
it's WordPress because they have been dealing with this problem

398
00:39:09,000 --> 00:39:13,000
on billions of websites for tens of years.

399
00:39:13,000 --> 00:39:16,000
So that library that they're using to do it is good.

400
00:39:16,000 --> 00:39:18,000
And this is a port of that to Swift.

401
00:39:18,000 --> 00:39:23,000
Yeah. Yeah, that sounds like a reasonable pick.

402
00:39:23,000 --> 00:39:25,000
You have a final pick?

403
00:39:25,000 --> 00:39:30,000
Yes, I do. I actually had only two. So that is perfect.

404
00:39:30,000 --> 00:39:35,000
My second pick is called Subprocess by Apple.

405
00:39:35,000 --> 00:39:38,000
Or should I say Swift-Subprocess?

406
00:39:38,000 --> 00:39:43,000
Because it's one of those cases where the URL is Swift-Subprocess,

407
00:39:43,000 --> 00:39:49,000
but the package name is Subprocess itself.

408
00:39:49,000 --> 00:39:54,000
And this is one of those packages that I was really looking forward to actually

409
00:39:54,000 --> 00:39:58,000
seeing pop up at some point.

410
00:39:58,000 --> 00:40:06,000
We probably all know Process, the foundation thing that's been around for ages.

411
00:40:06,000 --> 00:40:13,000
Lots of packages have actually sprung up to replace or wrap Foundation's original Process.

412
00:40:13,000 --> 00:40:18,000
And mostly these packages have sprung up to improve the ergonomics of it a bit

413
00:40:18,000 --> 00:40:22,000
because it can be--there's kind of weird parameters on it,

414
00:40:22,000 --> 00:40:27,000
especially if you don't need the standard out and standard error.

415
00:40:27,000 --> 00:40:29,000
It can be a bit weird.

416
00:40:29,000 --> 00:40:32,000
Or if you need them, it can be a bit difficult to deal with that.

417
00:40:32,000 --> 00:40:37,000
It has some sharp edges.

418
00:40:37,000 --> 00:40:43,000
And we ourselves actually ran into issues where Process has some internal issues

419
00:40:43,000 --> 00:40:46,000
that you can't actually fix from the outside.

420
00:40:46,000 --> 00:40:52,000
And for that reason, there's long been a newer cross-platform variant around,

421
00:40:52,000 --> 00:40:57,000
and it's been a Swift PM, like the Swift Package Manager,

422
00:40:57,000 --> 00:41:03,000
a submodule in Tool Support Core that ships with a TSC Process,

423
00:41:03,000 --> 00:41:10,000
I think is the name of the type that offers the functionality.

424
00:41:10,000 --> 00:41:14,000
So there was awareness that there are some issues around Process

425
00:41:14,000 --> 00:41:17,000
and that a replacement was needed.

426
00:41:17,000 --> 00:41:27,000
And I'm not sure to what degree subprocess now is based on TSC's Tool Support Core's Process,

427
00:41:27,000 --> 00:41:31,000
but the point is that there is now one.

428
00:41:31,000 --> 00:41:36,000
It has no tagged version yet, so if you want to adopt it,

429
00:41:36,000 --> 00:41:39,000
you'd have to track the main branch for the moment.

430
00:41:39,000 --> 00:41:43,000
But I'm hopeful that we'll see that soon,

431
00:41:43,000 --> 00:41:48,000
and hopefully then we can start moving.

432
00:41:48,000 --> 00:41:52,000
So we maintain a fork of a package that deals with Process,

433
00:41:52,000 --> 00:41:55,000
and I'm really looking forward to actually replacing that at some point

434
00:41:55,000 --> 00:42:02,000
with something that is maintained and hopefully does not carry the edge cases

435
00:42:02,000 --> 00:42:08,000
or the issues that the Foundation Process implementation unfortunately does carry.

436
00:42:08,000 --> 00:42:10,000
You're talking about our shell-out fork, are you?

437
00:42:10,000 --> 00:42:12,000
Yes, exactly, yeah.

438
00:42:12,000 --> 00:42:17,000
Great. Well, yeah, I think that it certainly sounds like early days for this package,

439
00:42:17,000 --> 00:42:22,000
although it has been in development for four months, so that's not nothing.

440
00:42:22,000 --> 00:42:27,000
But it does sound like early days, especially if it's not been tagged with a release yet.

441
00:42:27,000 --> 00:42:31,000
But yeah, one to watch for the future.

442
00:42:31,000 --> 00:42:32,000
Exactly.

443
00:42:32,000 --> 00:42:36,000
And with that, we will call it an episode,

444
00:42:36,000 --> 00:42:41,000
and we will see you in a few weeks for Episode 61.

445
00:42:41,000 --> 00:42:44,000
Exactly. See you next time. Bye-bye.

446
00:42:44,000 --> 00:42:46,000
All right. Take care. Bye-bye.