45: Lies, damned lies, and statistics

Did you enjoy WWDC?

Oh, I did. Yeah, it was nice.

It didn't last long because it got really busy when the Xcode public beta dropped

because we were in a hurry to get started with the processing.

So I stayed up to watch the State of the Union.

And I think at the same time the beta came out or something like that,

so I knew I was sort of on the fence whether I should start on it in the middle of the night,

but then I decided against it. So it was a Tuesday morning start instead.

So that sort of pushed everything towards the end of the week because we had some minor troubles

getting up and running with the beta. But yeah, it was a bizarre week.

There was the news on the one hand and then the busy period straight after.

So it wasn't like a normal week, really.

Sure.

How about you?

I think for me it was the best State of the Union ever, wasn't it?

It was really nice.

I'm referring, of course, to the fact that we got a call out from Ted Kramanek in the

State of the Union, which is a huge honor and something that we absolutely didn't

expect or assume that we would get. But it's a lovely thing to be mentioned in that session.

Truly one of life's goals.

So yes, it was really nice to see Ready for Special 6 get a mention.

And that's what Sven was talking about when he was talking about getting the builds

going on Tuesday morning. So I think it was actually, didn't we have a slight issue with

one of the parameters changing so that we couldn't actually kick it off until Tuesday

evening? But apart from that, the processing has gone extremely smoothly and we finished up

all Swift 6 builds using Xcode 16 beta 1 yesterday. And just about an hour ago,

before we recorded this podcast, those results are now live on the site.

And I was kind of curious as to what these results, what this version of the results

would look like, because up until now, we've been using Swift 6 nightly toolchains in Xcode 15.3

and 15.4 so far. And then when Xcode 16 comes along, the SDKs have now also been updated

to have sendable conformance in some places and just to the SDKs will be expecting Swift 6

and the compiler is now a default Swift 6 as well. So I was very curious as to whether we'd see

a significant jump up or down in compatibility numbers. The results are in and the amazing news

is it's actually a very consistent increase in compatibility or data race safety between

the last 15.4 build that we did and this 16 build that we did. So we increased from,

excuse me, we increased from 1,359 packages that have zero data race safety errors to 1,477. So

that's quite a large number of packages, well over 100 packages increase. But if you look at the slope

is a fairly consistent slope from previously. So it's just rising. People are doing the work to

get their packages compatible. The compiler is improving with more checks and less warnings

where it doesn't need them. And everything seems to be going in the right direction.

And actually I did a little calculation that this is almost 45% of all packages that are

free from data race safety errors, which is kind of amazing given where we are.

- Of the ones we're testing we should add, right? That's towards the baseline.

- Of the ones that we're testing.

- Yeah. It's maybe worth calling out at this point because I was actually briefly confused

when I looked at the, when we added the totals. We track 7,500-ish packages in total, but the ones

we're showing in these graphs, we are running tests for all packages. So on the individual

package pages, you will see, we'll be able to see the numbers, but in these graphs, we're only

showing recently updated packages. So that's why the total number is 3,500, because those are the

ones that have been sort of seen activity in the last, I think, what's the, is it a half year that

we picked as a timeframe? - I think it was a year, modified

within a year. - Yeah. And the reason to do that was to make sure that we sort of look at actively

maintained packages, because when you want to look at trends, we wanted to have a set of packages

that are reasonably likely to be currently updated, so they could actually see reaction to any of this.

- The one number that did spike though was the, so on our second chart on that page,

is the number of data race safety errors in total. So that's every package that we're testing,

just count up the number of data race safety errors that it got and add it, add them all

together. So you just get this huge number of total errors. And that spiked quite significantly

up from 53,000 errors with the last run to over 61,000 errors with this run, which

I'm not entirely sure of the reason for this, but I'm guessing there are, this is related to

warnings that are coming in through the SDKs that need fixing in people's use of those SDKs.

That would be my guess. - Yeah, I tried to have a look, but it was just too close to the recording.

And what I've seen, so I looked at the SSWG packages and the Apple package list,

because they are just smaller, so it's easier to compare package by package. And I've seen

a general trend of warnings going down in individual packages, and then a couple of packages

have huge spikes. And I can only guess that something's tripping up in these packages,

or they hit certain scenarios where they suddenly get, like I've seen these jump by 100 warnings,

and that took their total up when in general, the trend was to go down. And that's the problem with

looking at these aggregates, right? You're going to, the distribution isn't equal, so you get these

weird trends. It'll be interesting to maybe look at a couple of packages individually to see

what the reason is there. We should maybe also briefly mention how we actually count, because

that's also probably worth taking into account. So when we say a package is-

- What's the famous phrase? It's the lies, damn lies and statistics, right?

- Exactly, yeah. And because what we do is we run builds across all the platforms, right? We try to

build a package for each platform. And then the question is, well, which errors do you count?

And what does it mean a package is free from data race errors for every platform?

And that's not what we do. So we say, and that can be argued, and that's just something we came

up with for now. If any platform build has no Swift 6 concurrency errors, then it is free from

data race errors. So that's not perfect, but we have to settle somewhere. And this is the decision

we made. If there's one platform where you succeed, then that gives you the, in the top chart,

that gives you an entry. On the lower chart, when we look at the errors, we didn't want to sum up

the errors across platforms because it's just, I don't know, it feels weird. We pick the maximum

of all the errors per platform. So you're sort of judged by your worst platform there.

And underlying all this, the build has to actually succeed to report back a count. So you don't need

to worry that if your package is broken on a platform, that this would impact this number.

In order for the Swift compiler to actually report back the Swift 6 error count, the build

has to succeed. So all these builds are actually, all these numbers are based on succeeding builds.

And I hope that makes sense. If you have any comments around that and suggestions how to

maybe derive those numbers in different ways, let us know. That's what we came up with for now.

So what you're saying is that if I wanted my package to pass all the tests, I could just

take all the concurrency out of one platform. Exactly. Make your users happy.

It's got zero data race errors, but it is terribly slow and hangs the main thread all the time.

Great. There have also been some changes to the page itself. I've been making

some changes to the charts. So as Sven mentioned, you can now see the totals on the chart. And this

is actually from some feedback that we received. And it was great feedback, and I'm not sure why

we didn't see this problem before we implemented this, but we have three different lines on each

of the charts and they all have different totals. And we don't show or say the totals anywhere on

the page, which is less than ideal. So we now show the totals. So there is a thin line across

each chart in the color of the plot, and that shows the total. And you can also show and hide

those as well if you want to go back to the old incorrect graphs or misleading graphs.

So you can actually see kind of where we're heading now, how far are we? And you can see

that kind of 45% is much more obvious when you can see that total line. We also have

vertical lines on the charts now as well. So we can add events and there's an event that we've

added, which is the release date of the Xcode 16 beta one. And then you can see like a week later,

we have our next data point. So we've got some tweaks in there to the charts. We've also got

some tweaks in there to the frequently asked questions. Everything now should be kind of

up to date and ready to read. So I can't wait to see how this progresses throughout the summer.

- Yeah, let's hope the trend, well, at least the zero data races, package trend continues and the

other hopefully reverts back and goes back down because it was trending down nicely, the error

account before, but let's see how it goes. - Yes, I don't think we'll see another event like this

unless there is a significant change in the betas, which I'm not expecting.

- Yeah, it'll remain interesting, an interesting race for data race safety.

- Yeah. The last thing that we should talk about with the Swift 6 language mode

stuff is that we have added one more link to the page, which is a link to the Swift 6 language

mode migration guide, which is a document on the swift.org that explains a lot about data

race safety and how you might want to think about migrating your code base, how to obviously the

mechanics of enabling it and opting into Swift 6 language mode. And then some really useful

information about common compiler errors and how to fix them or how to think about the problems

that they are surfacing in your code. - Yeah, and we should also give Matt Mazzicotti a shout out

here, I think because he's helped craft this guide along with Holly Baller. And he's also

written a blog series about concurrency, Swift 6 concurrency, which is really interesting.

And he's been really, really active. - He also was the person who reported the totals missing

from the charts. - He's all over the place.

- We owe almost everything to Matt this week. - Right, so shall we do some packages?

- We certainly should. Yep. I guess it's fairly quiet in terms of news apart from all the Swift

6 stuff. So we'll get to packages a little quicker this week. - Do you want to kick us off?

- Yeah, of course. Yeah. My first package this week is, I love this package so much. I think it's

so clever. It's called Blur Hash Views by Dale Price. And so if you're loading images off the

web to display in your application, and you're not sure of how quick that data connection is going to

be, you're going to want to put some kind of placeholder in. And Swift UI includes a whole

load of methods to include placeholders, kind of standard spinners or loading indicators or

something like that, kind of out of the box. You don't need to worry about it most of the time.

Blur Hash Views implements a technique that is from a website called Blur Hash, which we'll also

include in the show notes. And what it does is it looks at a picture. So this is offline processing

before you get to the actual download. So if you have a set of images that you want to

load into your application, you offline process them so that you get a short blur hash string

to represent that image. And what a blur hash is, is let's say you had a portrait picture of a

person, kind of head and shoulders portrait. If they were standing against like a blue background,

then the edges, the top left and top right corners would both be that blue background.

And then in the middle, you'd maybe have some kind of skin tone colors, and then whatever

they're wearing, you'd see the colors of that in the bottom of the middle. And what it does is it

kind of picks out color areas on the image, gives them RGB values, and then makes a blurred version

with just vague hints of those colors in the right places on the image. And it creates this amazing,

really effective effect of looking like a blurred version of the picture by

representing it as a tiny amount of data. It's kind of 10 characters of data, something like

that to make one of these blur hashes. So if you're in the situation where on your server,

if you can process the image, figure out the blur hash and store that blur hash along with the image

that you're going to be downloading, then that is a fantastic way to give better image previews

to your asynchronous loading image views in any application, SwiftUI or

UIKit or AppKit or any of the platforms, this is going to be completely compatible. So

I really love this package. I think it's such a clever idea. And this is an implementation of that

algorithm that you can use with SwiftUI.

Nice. So what's the data you're getting back? Is that like coordinates, regions, and color codes?

I think the blur hashes, I think they look a little bit like a hex string. Here we go.

No, it's almost like a base64 string. So I'm kind of eyeballing it here, but it looks like about

maybe 25 characters of base64, which is tiny.

Okay. And the package comes with something that knows how to render that in a preview.

Yes, exactly.

Okay. I was thinking, well, how would you actually represent that? I get it. Okay, great.

Ah, okay.

And it recreates the blurs and the regions. And all of this is made possible. So this is taking

advantage straight away of our Swift 6 testing. Although it's not Swift 6 that it needs, but it

needs the new functionality in iOS or MacOS or VisionOS, all the platforms, it supports all the

platforms apart from Linux, but it needs the new functionality, which is mesh gradients. So there's

a new mesh gradient in Swift UI, where you can say, here is my gradient. And at this point,

represent this color, at this point, represent this color, and it will blend those colors between

each other. So it's a lovely implementation of a very clever idea using a brand new piece of

technology in iOS 18 and MacOS. What's it called? Not Sonoma, it's called?

Sequoia.

Sequoia. And of course, all the other platforms as well. I love it. I think it's just such a

great platform. Sorry, such a great package.

Nice. You actually just answered my next question, which was the representation,

if that's gradients and with the mesh, that makes perfect sense. Now I got a way better

picture now how that works. Very nice. That sounds great.

It's a very effective, very effective technique.

Nice. My first pick is a package called Decorative Text Kit by Christian Tietze,

which I found really interesting. So Christian has created a DSL for programmatic text editing.

So, for example, making changes to a text kit buffer without worrying about selection ranges

or insertion point invalidation, that sort of thing. Now I've done very little with Text Kit

itself, but I have an Xcode extension that edits the text, the Xcode text buffer. So I actually

had to fiddle with that. And immediately when I read that line, you don't need to worry about

reordering and selection invalidation. That really sparked my interest in the package because

it's the sort of thing, right, if you edit something at the top and you have selections

further down, you need to either update those regions or you need to go back to front to make

sure you don't invalidate the earlier things that you're messing with. So I found this really

interesting that he's managed somehow to come up with a decorative way of describing your edits

and then let the system sort out how it manages all that stuff, all that headache of indexes and

selection ranges and so on. So I found that really nice. I think it's text kit specific. So in my

case, that wouldn't actually help with my Xcode extension buffers, but I imagine that might be

possibly extended or to work more generally. I don't know. It might be interesting to

see where this goes, but it's a really interesting package if you're using text kit.

I'm so glad you've mentioned this one because I've been reading these blog posts that Christian has

been writing and was never quite sure how to talk about it. So I didn't link to it and I always said

weekly because I wasn't quite sure how to talk about it. So I'm glad you've mentioned it here.

You've saved me a job. You're welcome. My next package is called Swiftly and it is a package by

the new GitHub organization Swiftlang. So this is a, I think it's been around, it was under a

different, I think it was under Swift server before it moved to Swiftlang. Is that right?

Do you know that? It was. Yeah. It was. Yeah. And it's now moved to the new GitHub

organization Swiftlang, the official Swift programming language organization. And this is a

Swift tool chain installer and manager written in Swift. And the reason I think it's probably

worth mentioning at the moment, because this has been around for a little while,

is I'm not sure this is ready for kind of prime time yet, but you may have a better opinion on

this than me Sven, because I think you're a little closer being a member of the Swift

server work group, right? Yeah. And actually when I said at the start, I do in fact have

three packages. It's now reduced to two because that was one of my picks.

Yeah, you're right. I think it's absolutely ready for prime time in the sense that it is

ready for prime time on Linux, which is the first platform it actually targeted. The big drawback

up until recently, well, actually, in fact, it's not supporting macOS just yet, but there's a

pull request open to add it. So that should land very soon, which is the reason I

picked this again. I actually had picked it before, but I think it's really worth calling

out again, because it's been actually also mentioned a couple of times, I believe, at WWDC.

And because it's going to add macOS support really soon. And then it's really, I think it's going to

become the tool to do, especially things like we've been doing, like installing nightlies.

That's going to be much easier. And all that stuff. Sorry, but I didn't mean to hijack your

package. No, no. I think if we share a recommendation, we should share the description

of it. The other reason I mentioned it is that this is truly a collaboration between the work

groups as well, because one of the reasons I wanted to talk about it was we've been doing

some work through the Swift website work group to organize all of the backend data about nightly

Swift versions and where they are and what, you know, all the names of them and the dates and all

the rest of it are all organized through JSON files in the Swift website. So Swift.org repository

on, again, on the Swift, the new Swift lang organization. And so this is a wonderful tool

because it's been developed by, I think, Swift server work group originally. It uses, I think,

the majority of the same people doing their work on the Swift website. But it's a real testament to

how an open source ecosystem kind of comes together to thrive like this. There's nothing

proprietary here. There's nothing that is being used with secret data. This is all just open source.

Open source JSON files, which I am a big fan of. I've used open source JSON files into lots of

projects in my time and Swift package index uses an open source JSON file. I think they're a great

way to get data out there as a quick and easy API. So yeah, this is just a great package. It will be

something that will be useful for a very long time because we'll always have nightly versions of

Swift. And yeah, I'm pleased to see it thriving. Yeah. And by these JSON files, you are referring

to the metadata that Swiftly is using to discover Swift. Yeah, exactly. It's worth calling out

briefly. So originally Swiftly was developed by Patrick Freed. It's been recently maintained by

Adam Fowler and it's now via its transition into Swift lang, it's going to be actively maintained

by folks at Apple. I believe that's my understanding. I mean, Adam is surely still

going to work on it, but I think he is busy with his other open source packages, one of which I'll

be talking about in a minute. So I think he's actively working to help hand it over. Yes,

I can see that. I should have mentioned that as well. Patrick is by far the biggest committer on

this and has had consistent activity on it for the last year or so and only recently has other

people taking it on. So it's definitely worth a shout out to Patrick for his work on this.

Right. My second, third kind of pick is the package I just alluded to by Adam Fowler. It's

called Hummingbird, which to my surprise, I don't think I have picked before. And I was really

reminded that we should be talking about it because it was also mentioned in a WWDC session.

The session on Swift on servers was actually used to create a little service there. And Hummingbird

is a lightweight, flexible, modern server framework written in Swift. And it's very

imminent that the version two is going to land, which is fully async await. So Adam's been working

on a big rewrite on this and this should come live very soon. It's actually also, I should

mention this, it's going to be demoed in the upcoming Swift on server workgroup meetup,

which is going to happen in, I think, in a week's time. Let me just quickly verify this.

It is going to be happening next Thursday. No, sorry, next Wednesday, June the 26th.

And we'll have a link in the show notes there as well, where Adam and Johannes will be

demoing Hummingbird. If you are confused what Hummingbird, how Hummingbird is different than

Vapor, I think, and if you know Python, otherwise this might not be helpful, but

my sort of mental map is Hummingbird is sort of the flask, is a core framework with some specific

extensions that you can pull in to do more stuff. So it's leaner off the bat, has fewer dependencies

to start with, and then you pull in other things. And Vapor is sort of the Django that comes with

everything included and you have pretty much everything there at the start and you're ready

to go. So that might be, if you're undecided which one to pick, if you're just starting out

with Swift on server, that might be worth considering. - And because we're an equal

opportunities podcast, if you're a Ruby person, that would be the difference between Rails and

Sinatra. - There you go. Excellent. - Do we know what it would be in JavaScript? - I do not know.

I don't know. My server-side frameworks and JavaScript knowledge is limited. - No, I've

never actually used one. I've done Python a fair bit and some Ruby way back, but... And I hadn't

heard of... What is it called? Sinatra? No, it was something... - Sinatra, yeah, is a lightweight

version of... And again, you can bring modules in to bulk it up, you know. - Yeah. Nice. So there

you go. That's Hummingbird by Adam Fowler. - Wonderful. My final package for this week is

called Contrast Kit by Mark Battistella. And Contrast Kit is a library that helps you deal

with color contrast between foregrounds and background colors with a specific focus on

keeping your text accessible no matter what base color you're going to be using. So

there is a point at which white text on certain colors looks better than dark text on certain

colors. So as the brightness of a color increases, there will be some kind of point where it flips

from being more readable with white text on top to more readable with dark text on top.

And I remember learning about this years ago now, that that point is not just 50% of the way

through the brightness scale. Your first instinct might be to say, well, if it's more than 50%

brightness, then it's dark. If it's less than, it's light. But it's not that. There is a calculation

that you can do to figure out when that point occurs. And of course, if you're

hovering around that point, nothing's going to be particularly legible because if it's right on the

cusp of being one or the other, then neither are probably very good. But what this package does

is it takes all of that out of your hands and it says you can get any color. And then there are two

methods that I'm just looking up the names of now. There are two methods.

One is called highest rated contrast level. And the other is called double A large contrast level.

And they are different levels of contrast. So highest rated would be, give me the best color

that you can get that is going to be most accessible on whatever this background color is.

You can also lighten or darken any color by a certain shade. So you can kind of go through

from an almost white version of any color to an almost black version of any color in gradations

of kind of 5% of the color spectrum, which is just a really useful package. And especially

to just be able to say, well, it doesn't matter what background color this is. I know that my

text is going to be accessible if I use this package. - Nice. That sounds really useful.

- Works on all the platforms, supports Swift 6, and it is safe from data races.

- Nice. We've got a new call out. - Actually, I'm not sure we actually,

yeah, I'm not sure we actually mentioned that. We've talked a lot about the Ready for Swift 6 page.

But we've also gone live this morning with a feature that on package pages, there is now an

additional piece of metadata, which is whether this package that you're looking at is or is not

safe from data races. So that's just above the keywords on the package metadata section of the

page. And you'll see a little checkered flag, which I must admit, I'm quite pleased with how

that icon came out. I drew that from scratch and it came out much better than I expected it to.

- Yeah, I love that. I love that little flag. Yeah, that's a great shout out. I'd completely

forgotten about that because that's probably a thing as a package author, you want to know, right,

where do I land in that plot? And this is where you can see. If you hover over the thing,

you actually see the error count. We don't have, at the moment, we don't have a better way of giving

you more detail. We might be adding that in perhaps the build details page at some point,

but for now, that's where you can check what the error count is for your package.

- And I think I would guess the reason that this is safe from data races is it has no concurrency.

I can't imagine why this would need concurrency.

- That's an easy way to get there.

- That is the easiest way. It's my trick that I mentioned earlier, just take all the concurrency

out. It's easy. - Or just put it all on main actor.

- I don't know what all the fuss is about. - There you go.

- Right. And with that, I think we'll wrap it up here, call it an episode, and we will be back

in a couple of weeks or a few weeks with another one. We'll do it all again.

So until then, I will see you in a few weeks. - See you then. Bye-bye.

- Bye.

Creators and Guests

Dave Verwer
Host
Dave Verwer
Independent iOS developer, technical writer, author of @iOSDevWeekly, and creator of @SwiftPackages. He/him.
Sven A. Schmidt
Host
Sven A. Schmidt
Physicist & techie. CERN alumnus. Co-creator @SwiftPackages. Hummingbird app: https://t.co/2S9Y4ln53I
45: Lies, damned lies, and statistics
Broadcast by