It's episode 60 of the podcast, which episode 60 doesn't sound like a huge number,
but actually 60 episodes at the pace that we record them is actually quite a long time.
I'm not sure if that's a good thing or a bad thing.
Well, I mean, at least we keep doing it, right?
I mean, we've... so how many years is it actually?
Is it... well, it's certainly two, right? It's more than two years, isn't it?
Oh, way more than two years. It was... I think it was maybe 2021 or 2022 that we started it.
Oh, wow, that's how long.
I think so. I don't have a Twitter account anymore even.
And it was the first ones I would need to look up on Twitter
because they were only done through Twitter.
And so I don't know whether we'll ever know what the original date was.
I think that information may be lost to time, but it's certainly several years.
Well, there you go. Yeah, actually, during the holiday in Germany,
somehow we got to the topic and we talked to...
they always ask, you know, what am I doing and stuff.
And I said that we do our thing and that we also have a podcast.
And they got a surprise, "What? You have a podcast?"
And I said, "Yeah, it's actually been running for quite a while now, a couple of years."
And that's why I wondered how actually how long it's been.
So, yeah, it's been a while.
It was definitely kind of...
It was definitely not earlier than 2021
because I remember recording the episode that we did with Simon Støvring.
I remember where I was for that and I was in Basel in Switzerland.
And so that dates it as after all the lockdowns finished.
But I think it was only just after the lockdowns had finished that that was happening.
Yeah, I mean, it definitely wasn't in 2020 because we were still...
That was early days, which only just launched.
And then we had the bill system and, you know, that was just...
I think it was late '21, early '22, something like that.
That sounds about right.
So, 60 episodes of package talk.
How do we fill the time, I ask myself?
Yeah, it's funny how you think you don't really have a lot, you know, especially in summer.
I mean, there's WWDC, obviously, but there's also this phase when everyone is just busy looking at stuff.
And, you know, sometimes there seems to be a bit of a news gap, but there's always something, apparently.
Yeah, there's always something.
And today, one of the things that I want to talk about is...
We've actually talked about this on the podcast before,
but it was really, I think, just a passing gripe, actually, that we both...
I know we both share this gripe.
And that is the prevalence of packages that start with the word "Swift" in the Swift package ecosystem.
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.
And just to be clear about the problem,
I think both you and I believe that having the word "Swift" on the front of every Swift package is useless.
Every search result that comes up starts with packages that begin with the word "Swift" and it is the Swift package ecosystem.
It's not...
Yes, there could be code from other languages inside the package, but that's not what is important with a package name.
It doesn't really matter what the underlying code is to the consumer of the package in terms of the package name.
So that's the issue we're talking about here.
And I had a quick look at the database and out of the 9,300-ish packages that we have,
8.5% of them include the word "Swift" at the beginning,
which is almost 800 packages with the word "Swift" at the beginning.
And I think it's not unreasonable to say that this is Apple's fault.
[laughter]
I think this is quite clearly Apple and the Swift language team's fault,
because if you look at the statistics on a combination of the Apple and Swiftlang GitHub organizations,
they have 94 total packages between them and 79 of them start with the word "Swift".
Can I just ask...
85% of their packages.
Can I just ask before we go further, which part of the metadata did you check?
Did you check the repository URL or the package name?
I checked two things.
Right, OK.
I checked both.
I checked both the repository URL and the package name.
And if either of them were Swift, I included it.
Right, OK.
So it is the most sympathetic number to my argument,
because if somebody had set the package name as something different...
I could check this and we could follow up on it next week or next time,
but I don't believe that the numbers would be significantly changed by that.
But I did want to include package name in it, yeah.
Yeah, plus I'm not even sure if it's better or worse, if it differs.
We have cases where a package is called "Swift-Foo", but then the package name is "Foo".
That's marginally better, because then at least what you import is closer to the package name,
but then again the package name, I'm not even sure where stuff shows up how,
because SwiftPM, I think, looks at the base name of the URL pretty much for resolution.
And it's all kind of a mess, so you actually might even want to prefer to have it be the same, right?
Swift-Foo and the package name is Swift-Foo, so at least that doesn't...
But it's like every time I create a new package, you hit this, right,
where you think, well, what's it going to be?
What should it be?
Is it...
It's just weird.
It's just so weird.
I have thoughts.
It's just...
It's so superfluous, yeah.
And it really does affect things like search results.
Like everything just starts with the word "Swift".
This is not just...
I mean, programmers are famous for having little gripes that they kind of latch onto and never let go of.
But I think there's actually something real to this.
This is not just purely a little gripe, although I will admit it is also a little gripe that I have.
But I think there is something to it.
Anyway, I think the last time we talked about this, we had probably the same,
roughly the same conversations we've just had right now.
And we didn't really do anything about it.
And the reason I'm bringing it up again is I think it might be worth actually having a conversation about this.
Because if there's anybody in a position to at least raise this question, I think it's us managing the Swift Package Index.
And there's not enough explanation, if any explanation, of why it is this way.
That I think one of two things would be useful here.
Either just to find out if there is a reason, if this is a plan,
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.
So it seems to be intentional.
Then understanding why it is that way would be very useful.
And we can potentially help to get that message out there if that's the plan.
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?
I think we talked about, I think it was the last episode, we talked about the Swift ecosystem steering group.
It struck me that this might be the perfect venue to ask this question.
And actually, so this came up a couple of weeks ago.
Somebody did a pull request to the Swift.org repository.
It was about package ecosystem stuff.
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.
And it wasn't the right venue for that conversation.
And as soon as I typed the message, I realized it wasn't the right venue for that conversation.
So I left, I dropped it there.
But it did make me think, what is the right venue for that conversation?
Because I think it's a worthwhile conversation to have.
Yeah, absolutely.
Yeah, and I mean, even the answer might be it's just Apple who want it that way.
But, you know, that would be good to know because people are copying it.
And if that's, you know, sort of a side, I think that would be a terrible side effect.
If that's really only Apple's way of doing things, for whatever reason, it would be good to know.
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.
Like to me, it feels like early on when Swift was the exception, like it carried information, right?
It wasn't clear whether this was an Objective-C library or a Swift library.
And at that point, it might have been useful to have Swift networking.
And to be clear, you can use this with Swift directly without having to fiddle around.
But we're long past that point, right?
These days, you'd have Objective-C dash library to indicate that that's where it came from.
Let's not start with that.
I'm going to pull you back from that one right away.
Well, I have that in my notes, right?
If there's a Swift package with Objective-C code, it should be Swift dash Objective-C dash foo.
But, you know, it feels like what we're doing right now is we're doing file name suffixes in Swift package prefixes.
It's like at least stick it on the end, right?
If there needs to be something, just stick it at the end then.
So at least the sort order in Xcode and in other places, VS code, where you have a list of packages has some meaning.
Because right now, it has very little meaning.
There's packages that have, I say, proper names that are then sorted properly.
And there's a whole host of Swift dash names that are just sticking typically towards the end of that list.
And it's just weird.
Plus, you just cut off a significant part of your column width with information.
So if you stick it at the end, at least, you know, sort order is better.
And if it's truncated towards the end, that's not a problem either.
It's just, it just annoys me.
You said that it was spreading, and it is spreading.
So 79 Apple packages now result in 792 other packages.
You know, this is not just a few packages.
This is hundreds and hundreds of packages.
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?
I'd let that go.
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.
And then doing an import dependencies is such a, it's not connected, right?
If the package was called dependencies, and you import dependencies, that makes so much more sense.
Like, it's, we have Swift dash foundation, and we import foundation.
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.
And it's just bizarre that this is a handled so very differently.
It's, it drives me wrong every time I see it.
Me too. And I don't bring it up every week, but I want to.
So here's actually, you know, bear in mind, we actually have a restraint ourselves.
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.
Yeah, yeah, that'd be nice.
Great. Okay, gripe over.
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.
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.
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.
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.
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.
There we go again with the Swift hyphen.
I was just going to jump in.
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.
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.
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.
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.
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.
Yeah, yeah, exactly.
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.
So there's no point taking that out because there's a couple of packages already using it.
And there is just one thing, I was writing up a little bit of documentation for it yesterday, I think it was.
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?
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.
Because you could just skip your entire compilation, really, if it was in that environment.
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.
And so we're going to publicize this, obviously, in the documentation, we'll talk about it here.
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.
Yeah, exactly. Don't know. Not much to add, really. We'll be on your case if you try and do that.
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.
Do we have any other news or other items to talk about before we get into package recommendations?
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.
And he mentioned a Rust paper or a paper based on Rust or using Rust to implement something that I found quite interesting.
It's a tool called Paralegal, which is a static analysis tool for privacy bugs.
And I thought that was interesting for a number of reasons, despite it being Rust.
First and foremost, privacy issues can be quite significant issues.
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.
Obviously, not as important as package naming either. I mean, that's the real issue that we're dealing with today, right?
No way. But if you think of it in terms of GDPR, for instance, there are requirements on you handling data.
Like there's a requirement for you to offer data deletion when a user requests some account deletion.
You have to delete all associated data. And, you know, the enforcement is lacking a bit in the EU regarding that.
But that's probably not something you want to count on forever.
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.
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.
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.
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.
So you have a bit of a disconnect between the two teams managing this.
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.
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.
There are also some specialized tools that do this, but they're often domain specific like targeting SQL or database tables and stuff.
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.
You have nothing that has a holistic view of everything.
How is that being dealt with?
So what this paralegal thing does, it uses Rust's, like something similar to Rust's borrowing mechanism.
It has annotations where you annotate your code with stuff that is privacy relevant, like data.
This is privacy relevant data.
And then you can annotate other parts that handle the data, like, for instance, deletion, a function that deletes data.
And then the static analysis tool would ensure that if you have a rule, this must be deleted under certain conditions.
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.
And it can do that in real time.
So once you have specified the rules and instrumented your code, the instrumentations live alongside your code.
So it's, you know, it's not, they're not easily stripped.
They'll be there as semantic annotations.
And you always have this almost like a unit test.
You always have this being checked as you work on the code base.
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.
They're intended to be managed by a team that is in this different domain that deals with the legal side of things.
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.
And I find that really interesting that this is actually possible, that it exists.
And obviously Swift has many similarities to Rust, right?
There is borrowing now in, I'm not sure which Swift version that landed in.
Was it 6.1 or was it upcoming in 6.2?
I don't know, but I know that it sort of has that capability now.
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.
I wonder if that's going to be one of the future things, shipping at some point in Swift to allow that.
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.
But I did skim it and in today's world, surely that's enough, right?
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?
This feels like a higher level task actually.
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.
Because as soon as you move up in the code towards the user interface, you have to remember to check these things.
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.
So the more I thought about it, the more I thought it was a sensible way to approach it.
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?
The concurrency and concurrent access is all actors and stuff.
That's all type system mechanics to ensure that stuff is working correctly.
Like memory safety is all type system.
Borrowing is handled by the type system.
So it kind of makes sense to leverage that again, right?
Because privacy relevant data is sort of a specific type of data.
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...
In my mind, I haven't read the paper in detail either.
I mean, it's beyond me.
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.
It's sort of like handling that special kind of memory with a special kind of borrowing mechanism.
It makes sense that this is kind of similar, right?
I'm surprised that it does work.
And obviously, you need to annotate stuff, right?
You will need to tell the system, well, this is a function that deletes data.
And obviously, at some point, you'll have to ensure that stuff works as expected.
But there's a lot beyond that, that the thing can check that you don't forget.
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.
And that sort of stuff, even though it might seem trivial, is stuff that that's how stuff happens, right?
These links break as you maintain a system over time and stuff happens to not be called anymore.
And especially deletion isn't typically something that's in the hot path, right?
You don't notice that stuff hangs around.
You notice when stuff's gone, right?
When you do your testing, it's very easy to overlook that you've left something lying around.
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.
So it kind of made sense to me.
And I'm curious if we might see that in the, well, it's probably in the far future of Swift.
Swift 26, yeah.
I will include a link in the show notes to that article if any of you also don't want to read the paper.
Or if any of you want to read it and then come back at us and explain how we got it wrong.
Explain why we're wrong, yeah, exactly.
Let's go straight into some package talk then.
I'll kick us off this week with my first pick is a package called Cadova from Thomas Franzen.
And this is actually not a super old, sorry, a super new package.
This has been in development for four years.
But it's the first time I came across it this week.
And it's a kind of interesting concept.
So the way that I would describe it is Swift UI for 3D printing.
You get a kind of result builder style interface to building 3D models.
So, for example, one of the examples in the getting started guide is to say,
make a box of size 10, 10, 5 in whatever units it uses.
I'm not actually sure what the units are, but they are not specified in the example.
So 10, 10, 5 box, subtracting a sphere of diameter 10, translated on the Z axis by 5.
And so what you get there is a cuboid, which is an elongated rectangle.
Is that a cuboid? I think it is.
With a chunk taken out of the side in the shape of a sphere.
So a sphere intersecting the cuboid, then subtracted.
And I'm guessing you could make reasonably complicated designs like this.
But that you could store the kind of the template for those 3D printing files in code rather than...
Well, actually it does. It generates what's called a 3MF file,
which I presume is the file that you give to your 3D printer.
But I thought it was a nice way to think about this problem.
Interesting. Okay.
So that's probably something if you have lots of stuff that is kind of similar that you want to generate, right?
Because, you know, in general, you'd probably want to rather...
Yeah, you could.
You can't draw it, but I guess that makes sense if you automate stuff.
If you were iterating over something and, yeah, or taking a subtraction out of several pieces
and then splitting them up into... I don't know. I don't do a lot of 3D printing.
But I thought it was interesting.
The README file for this is okay, but it's not great in that it doesn't actually give any kind of examples.
But if you... In the first section of the README file, there was a link to a Getting Started guide,
which is a markdown file on GitHub that gives you a nice example and a screenshot of the resulting shape.
So it's obviously difficult to talk about this kind of stuff, 3D visualizations,
but go and have a look at the Getting Started guide.
My first pick is called Swift QC by Sheldon Aristide.
And QC is not Queen's Council. This is based on Haskell's QuickCheck.
So it's a testing library. That's what Haskell's QuickCheck is.
And the point is it's so-called property-based testing.
So what that means is effectively you don't write an expect expression where you have sort of static content on either side.
You sort of write down a... You have a closure where you take arguments.
And I'd probably best just give an example.
So you have a forAll function, and it takes this closure.
And for instance, you'll say you have two strings, and you say string1 plus string2 is a combined string.
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.
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.
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,
that might be sort of magic numbers, or you might hit some magic numbers, and then for other numbers it might fail.
Or inputs, I should say, not numbers.
And this forAll will actually take types that it then picks values from to run, like over a...
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,
or the expectation holds for the values that it puts in.
So it'll do that for a range.
And the interesting bit, on top of just doing this, is that if it finds a violation of that expectation, it'll actually...
This is called shrinking. It'll shrink the inputs to find the minimal inputs that also fail and give you that result.
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.
And it'll do that automatically.
And this comes with lots of implementations for existing types, like the standard library types, like strings, ints, dictionaries, arrays, and all that,
have all this already provided.
Like there's an arbitrary protocol, it's called arbitrary.
If you implement that in your types, you can also allow them to be used as inputs to do this picking of inputs.
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.
Because, as you can imagine, depending on the type, it might be very different on how you actually make it "smaller".
So yeah, I found that really interesting, and I know that this is a big thing in Haskell to do this kind of checking,
because the functional languages often are... The thing that you check is your functional implementation,
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.
The other thing to say is, this works, so this exists both for XCTest and SwiftTesting,
but it's actually one of those libraries where SwiftTesting has a quite nicer implementation,
because the error reporting is improved in the sense that it'll only...
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,
it'll only report the final minimal result that it found.
And in XCTest that's not possible, but with SwiftTesting that's actually possible,
because it can mark these errors specifically so they don't clutter your error reporting,
and you only get the final nice result at the end.
So there you go, a nice testing library, and one that actually makes use of the new SwiftTesting affordances to make it nicer.
Fantastic. My next package for this episode is called Email Validator by David Sherlock.
Actually I'm not quite sure if it's by David Sherlock or David Michael.
The author information says David Sherlock, the GitHub author says David Michael,
so I'm not 100% sure on the author name there.
This does pretty much what you would expect it to do.
Hands up if you have ever validated an email address with a regular expression.
I know I'm putting my hand in the air right now and I'm sure Sven is as well.
How hard can it be?
How hard can it be, right? How hard can it be?
This does not use, well actually I'm not sure what it uses behind the scenes,
but what it says is it says it uses WordPress's battle-tested validation logic,
which I'm sure there are probably regular expressions in that,
but it's certainly more than a simple single regular expression.
It validates based on the RFCs, first of all.
It has zero dependencies. It has provider detection,
so recognizes major email providers and can tell you whether an email address
is likely a personal or a work email address.
It also deals with all of the edge cases of email addresses,
like for example there's characters that you might not think would be available
to an email address that are perfectly valid within an email address.
It also does normalization of emails, so lower casing basically of email addresses.
Actually it seems to be slightly more subtle than that.
It says it's a lower case domain, so it keeps the username capitalized as the input,
but the domain gets lower cased.
It just copes with all these different situations where you might make a mistake
when handling email addresses, which is something that most applications
need to do at some point.
I thought that was just a really nice little package.
It's only nine days old, so it's a fairly new package, this one.
Actually currently, I should mention that it does not have an open source license.
It has no license, so you should not use this at the moment,
but I'm guessing given that it's only nine days over,
that is an omission rather than anything intentional.
Hopefully David will get that sorted out and put a license on it,
whatever the license he intended it to be under,
that he should make that explicit in the repository.
Nice. Yeah, that sounds like a great package because checking email addresses
for validity must be a nightmare, right?
Because also even providers implement this differently.
I'm not sure if it checks any of that, but you can add the plus something at the end.
Not all providers allow that. I think that's RFC compliant. I'm not sure.
It's just a minefield.
Plus is a valid character in any email address.
It's just that some providers then choose to implement that to mean a filter
or a filterable thing inside the mailbox.
But I think the key thing here is that if anybody can validate an email address,
it's WordPress because they have been dealing with this problem
on billions of websites for tens of years.
So that library that they're using to do it is good.
And this is a port of that to Swift.
Yeah. Yeah, that sounds like a reasonable pick.
You have a final pick?
Yes, I do. I actually had only two. So that is perfect.
My second pick is called Subprocess by Apple.
Or should I say Swift-Subprocess?
Because it's one of those cases where the URL is Swift-Subprocess,
but the package name is Subprocess itself.
And this is one of those packages that I was really looking forward to actually
seeing pop up at some point.
We probably all know Process, the foundation thing that's been around for ages.
Lots of packages have actually sprung up to replace or wrap Foundation's original Process.
And mostly these packages have sprung up to improve the ergonomics of it a bit
because it can be--there's kind of weird parameters on it,
especially if you don't need the standard out and standard error.
It can be a bit weird.
Or if you need them, it can be a bit difficult to deal with that.
It has some sharp edges.
And we ourselves actually ran into issues where Process has some internal issues
that you can't actually fix from the outside.
And for that reason, there's long been a newer cross-platform variant around,
and it's been a Swift PM, like the Swift Package Manager,
a submodule in Tool Support Core that ships with a TSC Process,
I think is the name of the type that offers the functionality.
So there was awareness that there are some issues around Process
and that a replacement was needed.
And I'm not sure to what degree subprocess now is based on TSC's Tool Support Core's Process,
but the point is that there is now one.
It has no tagged version yet, so if you want to adopt it,
you'd have to track the main branch for the moment.
But I'm hopeful that we'll see that soon,
and hopefully then we can start moving.
So we maintain a fork of a package that deals with Process,
and I'm really looking forward to actually replacing that at some point
with something that is maintained and hopefully does not carry the edge cases
or the issues that the Foundation Process implementation unfortunately does carry.
You're talking about our shell-out fork, are you?
Yes, exactly, yeah.
Great. Well, yeah, I think that it certainly sounds like early days for this package,
although it has been in development for four months, so that's not nothing.
But it does sound like early days, especially if it's not been tagged with a release yet.
But yeah, one to watch for the future.
Exactly.
And with that, we will call it an episode,
and we will see you in a few weeks for Episode 61.
Exactly. See you next time. Bye-bye.
All right. Take care. Bye-bye.