52: In the next episode we'll fix the NPM ecosystem

We should start a podcast.

Let's get going. Do you want to start with the Python metadata stuff?

Yeah, sure. So I saw a blog post this week. In fact, it was passed to me by Peter Steinberger,

who passed over this blog post from Armin Ronacher, and he thought I might be interested in it.

And it's called Constraints are Good, Python's Metadata Dilemma. And it's basically a post

about a situation that they have in the Python package and dependency ecosystem at the moment,

where you can have this thing in Python. I haven't really used Python. I've done a tiny

little bit in Python, but nothing worth mentioning. And I wouldn't say that I know

the language or certainly don't know the dependency ecosystem very well in Python.

I believe, Sven, you have done more Python than me, right?

I've used it a fair bit, yeah.

Yeah, so maybe you can guide me through this. So basically, the dynamic metadata is

in the kind of dependency manifest for a Python package. You can execute effectively arbitrary

code. And that is now causing a few problems, a very slow dependency resolution, and

difficulty with cache invalidation, fragmented metadata storage. I'm reading some of the bullet

points here from the list of issues in the blog post. And so first of all, correct me on anything

that I've said that's wrong there.

I'd be struggling because setting up dependencies in Python has always been weird. Like, I remember,

now this has been a while, I stopped using Python as a development language, pretty much when

I started on server-side Swift, which was around, I think the last project I used Python ended

like five years ago now. So it's been a while. But I remember, it's always been a pain point

setting up a Python project, because there's pip to install stuff. Then there was another thing

that was kind of, I don't remember, there was also running Python setup.py, the setup file

was a means to install stuff.

Right, I remember doing that a couple of times, yeah.

And I don't remember there was another one that was controversial. Or it might have just been

a dependency that's, I think that might have been a dependency that was setting up. My memory's

hazy there. But the one thing I always remember, I was always happy when I had stuff set up,

and I was successful. It was succeeding to import stuff. That was always the benchmark.

Can I actually import matplotlib and not have a library failing to load? Because the problem

with Python is, if it's a pure Python package, that was never a problem, right? That was always

smooth. The problem was always the dependencies that compile C code.

Like a wrapper or a C library or something.

Exactly, a C library, which is sort of also a thing that we are used to in Swift land, right?

Yep, there's lots of that in Swift.

To the credit of Swift, that's way more reliable than the Python stuff. Just because Swift can

actually compile the C stuff directly. And in Python, you need to have the C compiler and what

not installed at the right versions and all that stuff. It always ended up us writing a Docker

thing to set up stuff. It was always a bit of a pain. And reading that blog post sort of

gave me the idea, oh, this is even worse in areas that I wasn't even aware of. So I think this is

where I hand it back to you to summarize.

Well, and the blog post does mention, it says the challenge with dynamic metadata in Python is vast.

But unless you're writing a resolver or a packaging tool, you're not going to experience

the pain as much. And so this is, we're not talking about the entire environment of writing

Python here. But what it did do was this, and we'll link to this blog post in the show notes.

But what it did do is it reminded me that we have a slightly similar approach in Swift package

manifest, which are Swift code and not metadata. In fact, the start of the blog post, you always

know it's going to be an interesting blog post when the start of the blog post admires the

JavaScript package ecosystem.

But there is something about the JavaScript package ecosystem, which is good. And in fact,

there's a few things and he lists them out here. And that is that the package.json file, which is

the kind of container manifest for a JavaScript dependency, or a package, is a JSON file. So it

is not executable code, it is just purely metadata. And there's a couple of other things here. So

there's a one to one relationship between a package and its metadata in JavaScript, every

single package has one package.json file, which is the entire source of truth in the metadata.

That's good.

Which is also quite a baffling thing to have to call out, right? You immediately ask, well,

hold on, is that are there packages, because this is where that isn't the case where it's a one to

n or n to one relationship.

Swift does also have that one. We're one to one with JavaScript at the moment. Yeah.

Well, kind of, there's a caveat there, but we will get to that, I suppose.

Are you talking about the Swift version specific manifests?

Yes, exactly. Yeah.

Yeah, yes. Yes. I mean, we're already we're already I mean, Swift still feels it's not

a new language anymore, but it still feels kind of new as a language. And already we have artifacts

of things like that. Anyway, so the point that I was making here was, there are certainly aspects

of a Swift package manifest that came to mind as I was reading this blog post about the Python

dynamic metadata. And when we've hit problems where the compiled nature of a package manifest

causes problems for us, when we run the dump package command, which is supposed to turn a

package meta manifest into a JSON file, which is what we can then pass. And that's how we

extract all the metadata for about a package that we can get. And I think one of the key things that

that jumped out to me, which is mentioned in this blog post as well, is that based on, for example,

platform or environment, you can have your package metadata is not consistent. It is it can change,

depending on where you're compiling or where you're running that dump package command. And I

know, I know, I know there's a whole can of worms around opening a discussion on whether making

package manifests code was a good idea or not. And, and I also know that changing it at this

point would also be really difficult. And again, this is mentioned in the blog post, like once you've

once you have Pandora's box open like this, people build all sorts of stuff into that relying on that

feature, and it becomes incredibly difficult to roll it back. I feel with Swift, is it is it too

late to roll it back yet? I think probably not. I mean, we're still I just read a blog post,

actually, just before we recorded this podcast, which is the, the plan on when to make the Cocoa

Pods repository trunk repository read only, which is their plan to sunset Cocoa Pods, basically.

And I think they've given it a two year timeline from now, before they'll make it read only and

finally kind of completely shut it down. But Swift VM has over the last few years has become

hugely popular. But it was around for many years before it became hugely popular. It was around

before it was it was really useful in iOS and Mac OS projects. As I wonder whether we haven't quite

got past that point, where everything of the manifest format might be at least an option.

Yeah, I'd love to see that at least discussed. And then, you know, kind of decided,

looking at pros and cons. I mean, I, I, I'm not sure I entirely see the pros there.

Like, just just to give some context, just today. Incidentally, I fixed a bug that resulted from

having to have a compiler installed to to render the package manifest as JSON,

right, we our builder needs to run finds out some stuff about a package, in order to know which

a build command to run. And on Linux, actually, we run that in a Docker container that didn't

have the Swift compiler installed. And this was new, it didn't need we didn't need this before,

but now we did. And I, I was completely blind to the fact I had forgotten that our Docker image

doesn't have the Swift compiler. So I, I called right Swift, I saw that yeah, describe package,

and it failed. And then because of the way it was done, it sort of failed silently. And,

or at least it printed something that wasn't immediately obvious why that happened. And I

think that's kind of, it's kind of a heavy requirement that you need a compiler to

understand about your package. And then also, it's, it's important, you know, what platform

do you run it on, as you said, and what compiler version you're using to do that.

That sort of feels like, is that is that that's a bit, that's a bit weird. And then

we probably see more manifests than, you know, the, the normal because of what we do,

like we see lots of packages and people ask, well, why isn't this working? And

there's some wild stuff going on in package manifests, because it's effectively a little

Swift script, right, a Swift program, and it's programmed in it. And you have to effectively,

sometimes I look at these things, and I have to pass that program, because you know, what else

can I do? Obviously, you can run Swift package describe, and then get the output. But then that

doesn't tell you why stuff isn't, isn't there as you expect. And then you sort of have to sift

through and people do stuff in there. They import foundation, look at environment variables,

imply logic, and you think, Oh, God, is this? I mean, it opens up possibilities, but

I feel like some, you know, as the post says, you know, constraints are good, right? If

would, how, what, what would we lose if that was was just a JSON file?

Well, that's it. And every time I see somebody doing something like that in a package manifest,

I think, I kind of wish you weren't doing that. Like, wouldn't it be better if this was just a

standard file? My go to example, and I hate to call out a specific, a specific example here.

But they're a big company. So I feel I feel less guilty about it. My go to example for this is the

AWS SDK Swift package from AWS, which is a 627 line program in a package manifest. Now,

to be fair to them, they have they have 300, no 422 lines of targets, which is a lot of targets.

But, but still, there's, there's, there's code after that, which is doing all sorts of stuff.

It's looking at paths on the file system, it's it's looking at processes and getting environment

variables. And it's doing it's doing more than you would probably like to think it was doing if it

was just a package manifest with some metadata in it. And that's why I'd be really curious to

have a proper discussion and see, well, what use cases aren't possible with a, you know, static

JSON file or whatever it is, what we lose? Or is there even, I mean, the dynamism could be just

done upstream, right? That the output is a is a JSON file, right? If Amazon could, in that case,

have a Swift script that assembles stuff and then, you know, outputs a JSON file instead,

rather than, you know, keep that logic, you know, there on the fly sort of in the manifest.

I can imagine that there's stuff that is really hard to do, then, you know, like super platform

specific, how would that look? Like, would you have sort of logical structures within a JSON

file that says, you know, like, this is the dependency tree, if it's on macOS and Linux,

you know, how would that work? I mean, I can see how, yeah, that can get complex. But

that's a theme, the complexity is there. And it's just a matter of how do you package it up?

Because, end of the day, it has to be a has to be rendered out at some point is that how, how,

how much do you obfuscate it up front sort of is, I think, my right, my view of it. And

there is benefit and having these files more machine readable off the bat without having to

transform them, right? Because we like, always have to make sure they have a Swift compiler

and run Swift package describe or Swift package dump package in order to get the JSON out of it.

And that's the thing, you know, the JSON that we get out is the thing that we're interested in.

That's what we're using. And I sometimes wonder if that's not the, if that wouldn't be the better

intermediate format to keep around.

- Well, so just kind of make that not a generated artifact, but a stored artifact.

- Yeah, exactly. I mean, and then, you know, discuss, should there be something that can

generate it if you really have a very dynamic use case where you sort of need to, you know,

you sort of need to generate them, but then also bake them into a package, you know, so you don't

have, you can still be dynamic and then also write them out so people can actually get metadata info

without having to run the process every time, which is something we need to do, right? We have

a nightly that looks at packages and what we do is we fetch all the package manifests in a package.

And by all, I mean, all the versioned ones as well. So we have to make multiple HTTP requests

to get all the package.swift files out of a package. And fortunately, it's enough to copy

these in an empty directory and then run Swift package describe. That actually works. It doesn't

look at any other thing, other things in your package. It doesn't verify that you have a source

directory and whatnot. So that's enough to actually dump the package info then. But what we do is then

we render JSON out of it. So that process would be much easier if all we had to do is just fetch

a JSON file to begin with or whatever format is the one that's picked. It's just a lot of

work that needs to happen to get that data out. Yeah. Yeah. Just to flip onto the other side of

the argument and play devil's advocate, even though I am on this side of the argument,

there is one advantage to this that we benefit from, which is if it was a pure metadata file,

it would be more likely that we would let badly formed packages into the system. Whereas the fact

that we have to run package, the dump package before we accept a package into the index,

we get that we do get that level of verification that at least the manifest compiles.

Yeah, but I mean, there's Jason, there's Jason.

You could validate that and make sure that all the keys.

I'm back on this side of the fence. I attempted an escape, but it failed.

Resistance is futile.

Exactly. Exactly. Well, next week, we'll fix the NPM ecosystem and set that right.

Great.

There was another interesting post that I see

come out last week. Thanksgiving post by Holly Baller. And it's called prospective vision,

improving the approachability of data race safety. I'm sure you've seen that, right?

I did. And in fact, before you before you go into it, I want to read. I want to read Holly's

Macedon post where she where she linked to this, because it really made me laugh.

My favorite Thanksgiving tradition is a good language design debate ahead of the holiday.

Nice.

This time on improving the approachability of data race safety.

Well, Holly, I'm so glad that that is that's what was on your mind around Thanksgiving.

I hope I hope you managed to at least have some time not thinking about data race safety over the

holiday.

Well, isn't the US thing that Thanksgiving you go home to argue with your family? And that's sort

of that's probably what she's kind of doing with the other family.

I guess.

Anyway, let me I interrupted you. Sorry. I did see it. Yes.

Yeah, it's I really like this. I loved seeing this. It sets out to tackle some of the problems

that have come up when people start using Swift concurrency. And I think it bears repeating that

we are in the early stage of that adoption. And there's been quite a bit of noise because people

struggle with it, right? There's stuff that doesn't go as they as they planned.

Some of it is is compiler related. There are some issues that are

just growing pain in in Swift six language mode. So there's some some false positives and stuff.

And, and largely it sets out a vision on how to better deal with

with this with this adoption. Let me just see. Yes.

If she has a yeah, so she says she opens up and I should say, I found this post super readable.

People often think of Swift language development. Super in the weeds and you you can't follow and

there's there's that right often there are parts of proposals that are really technical and and

you need to know a lot upfront to actually even be able to follow but

you need to at least be be on the same page as a compiler engineer. Yeah.

I don't think this falls in that category. There's certainly stuff that you sort of

need to know a little bit about at least I think it's a bit hard to judge I I'm not a

Swift concurrency expert by by a long shot. But I also don't want to I mean, I've used it a bit. So

I'm probably more exposed to it than someone who's, who's just starting out.

Writing Swift or even someone who's only just starting to convert a project over.

But I think I think I'm not too sort of in the weeds already to be blind to

to, you know, that that threshold. I think it's quite approachable. And yeah, I think it's,

it paints the picture of what's what the problem is and what they're trying to achieve here.

So she opens up saying Swift's built in support for concurrency has three goals. And that's to

extend the memory safety guarantees to low level data races, maintain progressive disclosure for

non concurrent code, and make basic use of concurrency simple and easy, and make advanced

uses of concurrency to improve performance natural to accomplish and reason about.

And then she goes into, you know, sort of what are the remaining pain points where

what this is about is mitigating false positive data rate safety errors in

in sequential code and what the thing boils down to, I think, can be summarized in

the default is is sort of to assume that stuff is going to be running concurrently. And then

the compiler analyzes everything you do with that in mind. So anytime you touch, you know,

like global variables, for instance, the compiler will immediately shout, Oh, hold on, hold on,

what are you doing here? Remember, if you do this, there might be other concurrent access,

and that's not safe what you're doing. And what this is proposing is to flip this around

on a module by module basis. So to open up a mode where the default is to assume

main actor isolated code. And that means effectively running a single threaded program

on the main thread. And then if you mess with the global variable, that's safe by default,

because there's only ever one thread that can deal with that, right? There's no there's no

concurrent access because there's no concurrency. And that the vision is that should deal with a

lot of the all of the false positives right now, that can happen. And the false positives are

really shortcomings where the compiler can't see everything that's happening. And then,

because it has to be safe by default, it says, Look, this, this could be problematic,

I can't prove otherwise. So I have to warn about it, or, you know, in Swift six mode,

raise an error about it. And it's for you to be really explicit about what you're trying to do.

And by flipping this around, sort of the, the premise goes away, right? The, the initial

assumption where there might be a concurrent access isn't actually a problem anymore, because

there isn't concurrent access. So it that eliminates the need to raise an error by default,

and then you can poke holes into that by saying, Alright, this is actually non isolated, or has

different isolation, and then you can open up to concurrency, and then you get the richer warnings.

But the you can put this in a mode. And this is a mode that's really interesting, for example,

for scripts, or like in general is proposed to use in executable targets where, where you're going to

be starting with on the main thread, you know, like, if you write a script, you're probably going

to be on the main thread the whole time, right? And then why even deal with all this? And that's

the proposal is sort of to flip this around, I can, I hope I didn't mess this up describing what's

what this is about. Again, read it, because I think it's really readable. The discussion around

it is that's more in depth, because people raise, you know, concerns, how would this affect this and

that. And there are certainly aspects that are more complicated when it comes to classes and

inheritance and protocols, and then it gets a bit in the weed. But I think the basic premise

is quite graspable. It's quite obvious what this is proposing. And I think it's really well laid

out. And hopefully that will be accepted, implemented, and then could could be one of

those things. Remember, when we discussed this last time, we said, this is early days, just don't

rush into adopting Swift 6 by next year, things might be very different and might be much easier.

And that actually might be one of those things where you have a much easier time adopting this

in Swift 6.2.3, whenever this comes out, or is implemented. This might be one of those things

where you won't have to sprinkle main actor all through your code base, because main actor is the

thing that's going to be assumed, you know, wholesale, and you don't need to annotate stuff,

because it's sort of baked in into the module by module assumptions. There's one other thing I

wanted to highlight. And that's from the comments in this thread. Because that's also something

I at least said before, and I was really glad to see this echoed. And this is Tim Condon's reply

to a common complaint that data race safety annotations are a chore. And this is what we

talked about. I'm not sure if it was last episode or the one before. Tim says, to provide an

alternative point of view of this, I've lost count of the number of issues and data race issues

that have been caught and fixed by adopting Sendable across Vapors code bases. Lots of GitHub

issues that were impossible to reproduce, subtle data race issues, and downright stupid coding from

myself. Once we adopted Sendable, and yes, it wasn't an easy process, especially doing it as

an early adopter, all of those issues went away. We've not had a single issue reporting a crash as

a result of data race issues. And I was really glad to see that because I hadn't heard many people

say that thing that I've said before about our concurrency crashes that we've seen and that

disappeared once we switched to Swift 6. I think it really bears looking at these examples and

highlighting those so it's clear what you're getting. That it's not just a chore that you

have to deal with errors, there's something that it buys you. But, and this is also important,

we touched on this as well, to some degree, iOS doesn't have this at the same level, right? It

hasn't doesn't have the same level of impact on iOS. And I vividly remember when I was managing

an iOS team, when we were triaging iOS crashes, one of the things I looked at specifically was the

number of crashes per device. So the most important thing to fix was, we didn't want to have crash

loops on a device. If someone has a crash every once in a while, that was all right. If someone

crashed, obviously looking at the logs, the crash reports repeatedly, that was a problem. Now,

server code is different because you essentially run all the devices, right? You aggregate all

the crashes across the whole install base at once. So you have much more incentive to fix that.

But, and Tim says that Swift is just more than an iOS programming language at this point, right?

Yes. And you're right that it is really nice to see Tim's comment there. I hadn't seen that until,

I just looked at it while you were talking about it. And it is great to see a story like that. But

you're absolutely right that this is a language that has many different uses now. And still the

main use is from iOS and MacOS applications. So I'm so happy to see this document from Holly.

First of all, and we knew that they were still thinking about this, but this is

proof that they're still thinking about it. And it's nice to see, like, if you just look through

some of the headings in this document, some of the headings are really, they really spoke to me

actually, easing incremental migration to data race safety. I mean, the fact that that is a title

in this document is, it lifts my heart. It's great that that's the kind of thing that they're

talking about here. And obviously there is that the idea that you could switch an application to be

single threaded because some applications don't need concurrency. It's fairly rare these days,

even an iOS application, a simple iOS application will probably make some kind of network call.

And as soon as you do that, you need to consider concurrency in there. But there are certainly apps

that don't need it. And especially as people are learning the language. And I think that's one

thing. I wrote a few weeks ago about optimism in iOS Dev Weekly. And I use the example of how easy

it is to get up and running with Swift on a new Mac, a brand new Mac, a friend of mine bought a

new Mac. And I wanted him to run some benchmarks on package index, but compiling it with the M4

chip to see how it compared to my very expensive M1 Macs that I bought a few years ago. And I was

struck by how incredibly easy it was for him as somebody who is not a developer to get that,

get Swift installed and have what is quite a complex project compile. It was trivial. And

in response to that, my optimism and kind of choosing to see the good things about the

language, I got some real colorful feedback saying that even people who are trying to learn Swift are

hitting these concurrency issues immediately. And so I'm so glad that they're really putting

this into something that will hopefully be implemented. Yeah, it sounds like it's really

going to take the edge off some of this, the early stuff and Holly highlights that in an

explicit example. I think that it's unfortunate that in some areas you immediately get hit with

these warnings when you're doing something like obvious, you know, in a script, you know,

like a global variable, stuff like that. And if this is the way of dealing with that, that's

fantastic because it'll open up these use cases to be much smoother. I mean, we run a script to

validate our packages and that's sort of one thing where we haven't transitioned over yet. And that's

going to be a bit painful. And that might actually be a reason to wait and wait until we have that

mode and then just do it do it there. Well, almost certainly that doesn't need concurrency.

Well, it does network requests, and we might pass some stuff. So it's, it's kind of

but in that script, it could it could absolutely wait for that.

In the single package validation. Yeah, for sure. I'm thinking about the validator that crawls,

you know, does all the packages. Yeah, that's that's another one. Yeah. Yeah. I mean,

all of this. It's just great. But we've talked far too long about, about this stuff. So we should get

to some packages before people just stop listening. Yes, let's do some packages. Do you want to start

us this week? I'll kick us off. My first package recommendation isn't a package recommendation,

per se. It's a it's a package search recommendation. I came across a social media post

a couple of weeks ago, about a project called LMDB, which I'd never heard of. So this is sort of a

key value store database, which has fast transactional asset transactions, support,

thread safe, crash proof, broad platform support. And the person wasn't posting about Swift,

this was just a general recommendation to look at LMDB. When you might be looking at SQLite as

sort of a similar project, but you know, SQLite is very relational. And this is a key value store

thing. So this might be if you have key values, that might be more fitting. And then I thought,

oh, it's interesting that I never heard of this. I wonder if we have wrappers, because it's a C

based project, I believe. I thought, well, maybe we do have wrappers. And I ran a search, and I was

really delighted to find quite a number of packages related like this, I'll name four.

There's a couple more even, and obviously just the plain C wrapper as well. So we got quick LMDB,

rapid LMDB, Swift LMDB, kind of a theme here in the names. And then Empire is a quite differently

named one. And these all, you know, wrap this and have various different APIs. I didn't try any of

them. But they looked well maintained and had different, you know, different ways of dealing

or adding an API on top of it. I thought that was really nice to see that this is represented. And I

think the database itself seemed quite interesting. So if you have a need for a key value store,

give this a try. When you normally perhaps would have chosen SQLite, I think that's a

nice alternative, if you need something like that.

And does it have any, you may not know this, but does it have any, any dependencies on other,

like, is it built on top of another SQL? Sorry, another key value store? Or is it

purely implemented inside this package?

I, well, the packages themselves probably pull in the C sources, but the LMDB itself, I think is a...

Ah, so LMDB is the underlying. Okay.

Yes. Yeah, that's a, that's a, it's sort of think of it as this is SQLite, an alternative to SQLite,

which has the same thing, right? You typically use, have SQLite interfaces by pulling in the

SQLite C sources and then building those and then adding richer APIs on top of it. And that's what

these packages are, I think, are generally doing. I haven't looked at all of them in detail,

but I've seen a couple, you know, explicitly call out that they're wrapping the

C sources or the, I think it's C under the hood. They're pulling, well, it must be C or C++,

I suppose. So yeah, there you go.

Great. My first package is called Fuzzi, F-U-Z-I, and the developer name is DimensionDev.

I'm not quite sure who's behind it, but it is actually a port or at least a,

it's based on a port of Matt Thompson's Ono library, which was, I think, an Objective-C

library back in the, well, yeah, I've just looked at it. It's more than 10 years old,

the Ono library, and the last commit was five years ago. So an abandoned library for parsing XML.

So obviously Swift can parse XML, but unlike JSON, XML has kind of died as an interchange

format these days, often for good reason. You know, JSON is very much more efficient in terms

of size and all the rest of it. So there are huge and significant reasons why JSON won that battle,

but certainly people still need to parse XML from time to time. And the APIs built into

Foundation for parsing XML are okay, but they're a little outdated compared to how we interact with

JSON. And what Ono and more recent Fousey library do is try to bring a more Swift-friendly syntax to

parsing and reading data from XML files. So it's still parsed, powered by libxml2 underneath the

covers. So very, very fast parsing from that, supports XPath and CSS queries,

auto conversion of dates and numbers. It can load HTML and XML documents from strings or

NSData. So it's got all the kind of basics, but then there are some things in Fousey that have

been improved as well. Mostly the Swift-style API, no more return types like in any object,

with so you're much more type safe with this new framework. Some customizable dates,

number four matters. So there's a few other things as well, but effectively it's a modernized

and easier way to access and parse XML, which if you still have to do that, you might be interested

in checking this out. - Nice. That looks great. And, you know, such a rich history,

nine years in development. That's amazing. And you see the sedimental layers. If you look through

the readme, there's pod install, there's Carthage update. It has all the different...

- Actually, I've... So I may have been slightly tricked by this. I've only just realized this,

the one that the dimension dev one that I've recommended here, and this is not the first

time I've done this. It's actually a fork. So Fousey itself, the original packet is by C. Zeng.

And what we'll do is we'll pop a link to both of these in the show notes, because what I didn't

realize is that this is a fork. So I'm not sure, I'm only just learning this now. I'm not sure how

different the version I saw in the new packages list is from that fork, but certainly either of

them are an enhancement over the standard XML document and XML parser classes.

- Great. Very nice. Right. My second pick is called Orb by Siddharth Mehta.

This is a lovely package. It creates Siri-like orbs. And by Siri-like orb, I mean that

that swirling, you know, like circle animation when you bring up Siri on your phone or on the

Mac, I think it's sort of universal thing. And it has many other variations as well. And the readme

is really nice in showing those off. So, you know, there's a number of this mystic nature,

sunset, minimal, different color themes, and I suppose different animations as well.

I don't think there's anything... No, it's not actually showing a video because I imagine the

animations might be slightly different depending on which one you pick, but you can, you get an

idea for what color they look like. So if you need an orb, and who doesn't, this is a package for you,

I suppose. - Well, who doesn't need an orb in these times? - Yes. - All right. My last package for

this week is called SolverCore, S-O-U-L-V-E-R, by Solver, the company who produced the Mac app,

Solver, which is a calculator app, which I've used for many, many years now. And I dearly,

dearly love it. And the unique thing about the app is that you... It's kind of like a cross between

a spreadsheet and a calculator. So you can type in lines of text which get evaluated. So you can

type in a mathematical kind of equation or something like that, and it will give you the

answer to that. Sorry, not equation, type in just, you know, three plus four, and it will give you

the answer to that. But then you can refer back to previous lines. So you can say, take the output

of line one and multiply it by 20, and then carry on like that. And over the years, it's become more

and more capable. You can bring currency conversions in there. It makes requests out to

get up-to-date currency conversion data. And the reason I noticed that in the package feed this

week is that they've just released a version three of this library, which I guess tracks a feature

they've just added in the application itself, which is that you can have place data inside

calculations now. So you can say, for example, what is the time in Ubud, Bali, and it will tell

you that. And it knows where places are. So you can say, what's the distance between London and,

you know, Anchorage or something like that. And it knows about places.

But what I really want to talk about with this is how this has been split out into, so mostly what

I've been talking about so far is the app called Solver, which you should absolutely check out if

you haven't used it already. But what Solver is built on top of is this Solver core package,

which gives you that calculation engine in a format that you can use, including all these

fancy features like places and currencies and all the rest of it, that you can embed into your apps.

And I've seen many apps now implement this. So for example, if you're in like a design application

and you wanted to say, well, this box that I'm editing is, you know, 10 pixels wide,

and I wanted to actually make it 10 plus eight pixels wide, because I'm adding eight to everything,

let's say, or a whole load of boxes. If you put Solver core behind those text boxes, they become

little calculators where you can just on the fly do calculations. And that's such a powerful feature.

Now, the one thing I should mention here is that this is not a completely free or open source

license. This is, I'll actually read you the bit from the bottom of the readme file,

because it's important to note this before you kind of go off and start using this project.

You may use Solver core in personal or private projects, but please email us if you wish to

use it in a publicly available or commercial project. So it's fine to play around with it.

It's fine to implement something, but before you actually ship anything with it,

you need to contact the company. And it is actually a binary, there is a binary target in there. So

it's also, you don't get the full source code for this calculation engine, but I still think it's

worth checking out because it's such a powerful concept, I think. I love it. Yeah. I mean,

Solver is just such a great app. If there's a library that allows you to do similar things in

your own code, and even if it's just a personal project, that's just great. I think that's a

fantastic tool. Well, I've spoken to, the developer is Zach Cohen, and I've spoken to him

on several occasions, actually. And as I understand it, Solver itself is built on this library. So

this is the real thing. This is not some pale imitation. This is it. Yeah. Very nice.

All right. My third and final pick is called Q by Matt Mazzicotte. And I think this time I actually

pronounced Matt's last name correctly. I've messed that up a couple of times in the past. Apologies,

Matt. Yeah, I saw a podcast with him. I think it was the Dev Diaries that we were on.

Yes. Yeah, exactly. And it was at that point that I realized that we've been

pronouncing his name wrong. Sorry, Matt. So we spoke about Swift 6 and concurrency earlier,

and this is a really nice package to give you an async queue. So, you know, one of the problems

with structured concurrency when you do task groups is you have no control over the execution

order of stuff. If you have async blocks and you enqueue them in these task groups, they can come

out in, you know, like not entirely random, I suppose. But, you know, you can't rely on the

order, really. And this fixes that. So it's effectively like a serial or concurrency,

concurrent queue, just like dispatch queue that you can enqueue async blocks on. And if you run

it serially, like you would in a serial dispatch queue, you really have execution order guarantees

what you get out of it. So that's really nice. It has a couple of other API extensions,

like something like a barrier. Have a look at the README. It gives examples. I think it's really

obvious what it does and how to use it. And it might be a really good tool, especially when

you look at transitioning over and you might have a serial queue and might not know how to

transition that over into Swift 6 concurrency. This might be the thing you need in that case.

So that's Queue by Matt Massicotte. And I think that brings us to the end of another episode

of the podcast. It does. So I think this will be the last podcast for this year,

because we're heading, we're absolutely careering towards the holidays. And I have a feeling this

will be the last one for 2024. So thank you so much for listening, even whether you just listened

to this, if this is your first episode you've listened to, or whether you've been with us

since the beginning. I really thank you for sticking with us. And we look forward to giving

you more of the same and even better in 2025. Yeah, exactly. Thank you. And yeah, see you next

time. Bye bye. All right see you next time. 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
52: In the next episode we'll fix the NPM ecosystem
Broadcast by