49: 64 bytes of guaranteed uniqueness
So I think we can start with lots of news this week.
It's been a few weeks since our last episode.
We had to postpone last week,
which has given us a little bit of a chance
to get a little bit more queued up news,
but we have several things to talk about this week.
- Yeah, indeed we have.
Actually last week, I had just finished participating
in the Server-Side SWIFT meetup, the third one,
organized by the SSWG,
which is the SWIFT on Server Working Group.
There's just so much SWIFT and server in those names.
And I think this is of general interest.
I mean, it's a Server-Side SWIFT meetup and working group,
but the topics were actually
not all that Server-Side specific, I'd say.
So there was a great talk by Jutta Seito
about SWIFT WASM.
And there's a package also that I can mention
while we're at it, WASM Kit.
It's not a single thing.
So there are a number of things
that are sort of in the category of WASM.
And WASM, what does WASM actually stand for?
I keep forgetting.
It's Web--
- WebAssembly, I think, yeah.
- WebAssembly, exactly.
So effectively it's sort of,
I think, and Jutta had a really great way of phrasing
what, why WASM is such a big deal.
Think about what JSON has done for data exchange.
Like really, you mentioned JSON
and you want to receive JSON.
Everyone knows what you're talking about.
And it's just about what fields do you want?
But all the exchange format is really, really clear.
It's sort of become the de facto standard
for data exchange.
And WASM could be that for executable, for logic.
Because it's essentially something that can be produced
by various different languages, Swift being one of them.
So, you know, Rust, I don't know, I guess Python,
you know, all manner of JavaScript,
all manner of languages can produce WASM
as an executable format,
which can then run on many different,
in many different places.
Like the browser, they are just runners.
Like there's a thing that's actually written
in Swift that can execute WASM.
So it's a proper exe exchange format,
executable exchange format.
And it could be sort of the lingua franca
for exchanging logic.
You know, think plugins, you know,
what if you wanted to have plugins that are shippable?
That could be WASM.
There's a really great-
- I think that's-
- Yeah, go on.
- I think that's a really nice way to think about it,
actually, because I'm much more excited.
So I actually, I attended the meeting
and watched this talk on WASM.
And I actually, I asked the question halfway through,
which was, you know, how does it interact
with the browser APIs?
And I'm, and it does interact with those browser APIs,
but I'm much more excited about WASM
as a non-browser technology.
So I don't think I'm going to be rushing
to interact with the DOM
when we're doing the bits of JavaScript
that we need to do on the Swift package index in WASM,
because I don't really see any advantage to that.
In fact, all you get is a slightly degraded experience
because those browser APIs, they work,
but they're, you, it's not,
it's not how they were intended to be interacted with.
But for other bits of code
where you might have to either re-implement something
that you had in your server-side code or something like that.
And as you say, as maybe like an interchange format
for code, I think it's a much more exciting technology
in those cases.
- Yeah, exactly.
I mean, think of all the places
where you have executable code
that should run cross-platform, for instance.
And like one example that's been brought up
that has actually been pitched is macros.
So right now you have to include Swift syntax, right?
When you have macros and you want to generate the source code
and you have to build all of Swift syntax,
and that's a huge strain on the build system,
on your builds in particular, if they release builds.
WASM could be the exchange format,
such that you don't have to ship Swift syntax
in source, but you could ship it as,
my understanding is at least that it would be shipped
as a WASM build that then gets run.
So you skip the build step of it.
You automatically have a cross-platform plugin
and you don't need to ship like five different slices of,
you know, how would you even do that with Linux?
You know, you can ship a binary that runs
on macros, Intel and ARM, you know,
by having a binary that has the two aspects of it,
but that wouldn't work for Linux.
And then you'd have to bundle that up somehow.
But with WASM, it's just one thing that gets run
on different platforms because they know how to execute that.
So that's quite interesting.
Just give the, the meeting has been recorded.
So there's a YouTube up where you can watch the presentation
or it's really nice, really interesting.
Opens up lots of possibilities around that topic,
you know, executable logic exchange.
- Sure.
- Yeah, and there was a second interesting talk
by Konrad Marowski of the Swift team at Apple.
And that's also not, wasn't really server specific
because he talked about getting ready for Swift 6.
And that was a really interesting talk as well.
Was, he started, I think he started off with a reminder,
you shouldn't panic, don't panic about Swift 6.
It might even have been his first slide,
but he also had great tips on how to hold your towel
when you do panic.
And if you don't know the towel reference,
you can do a web search, but you know,
you might end up in places where you get warnings
and you don't know how to deal with it.
And Konrad had examples of those
and how you deal with them.
And I think that's a great talk
to take the edge off because I think,
and we've talked about this a number of times,
there is a lot of concern around Swift 6
and Konrad really addresses that
and calms people down, I think.
And he's done a really great job
laying out how you should approach it.
- That's great, yeah.
And talking of events, Swift events,
you are actually at an event where you will be,
by the time this gets released, you will be at,
you're not at, talk about a Swift event.
(laughing)
- Yes, I will be at the Swift on Server Conference
in London next week.
In fact, I'll be leaving tomorrow and this podcast,
I'll be ahead of the podcast
and the podcast will arrive after me there.
Yes, I'm really looking forward to this one.
Lots of people I've interacted with.
Online that I've never met in person,
so I'm excited to meet lots of folks.
I've already got a list of names of people
to get in touch with.
Yeah, exciting times.
Unfortunately, you're not one of these people on the list,
but we'll manage here.
- I'm afraid I'm not.
Yeah, like I said, I've not been super well recently
and I'm not gonna be able to be there this week,
which is a tragedy because I was there
the last time this conference was put on
and it was not only a fantastic conference,
but a great opportunity to meet a lot of people
who I hadn't yet met in the server-side Swift community
and it was a great event.
Fantastic venue.
I think it's at the same venue this year.
It's the Science Museum in London,
which is a fantastic venue.
And as you say, just a really good chance
to meet a lot of people.
But it unfortunately does mean
that we won't get a chance to meet up again this time.
- Yeah, unfortunately not.
But you mentioned, we were on a call yesterday,
you mentioned a cardboard cutout that exists of you.
And do you own that?
Could you ship that so I can prop you up here in my office?
- I don't own it.
No, at the end of,
so we'll pop a link in the show notes too.
This is something that happened a few years ago
and there's a whole story behind it,
which is too long to go into on the podcast.
But at WWDC and Alt Conf 2019,
there ended up being a life-size printout of me
that was put in the Alt Conf kind of main lobby area
for the entire week of WWDC.
And it was there for people to take pictures with,
which is the strangest possible backstory to this.
So strange, in fact,
that I felt I had to clarify it in a blog post,
which I did do,
and we'll include a link in the show notes to that.
But the main reason I wanted to clarify it
is just to make sure that people understood
that I didn't make a huge life-size cutout of myself
because nobody wants to be that person.
And that's not what happened.
But the slightly worrying thing is I didn't make it,
I don't own it, and I don't know where it is,
but I'm pretty sure it still probably exists somewhere.
- This was spawned by PicswithDave, right?
There was this Twitter thing.
- It was, yeah.
- I mean, be honest,
you just outsourced the PicswithDave
to a cardboard cutout, right?
(laughing)
- Exactly, yes.
Yeah, it's all Kevin Hocter's fault.
That's all everyone needs to know.
- Right, right.
- We also have a bit of contribution news
to talk about this week.
We have a couple of things I'd like to mention.
First is a contribution which is kind of in progress
at the moment.
So we've had a discussion around an enhancement
with Daniel Lyons, who came to the discussions board
on our GitHub project and suggested that we add
a new type of filter to the search options.
So we already have filters for things like
license and platform.
So you can say, show me all packages
that match this search string,
but also are compatible with iOS
or have a specific license or something like that.
And one of the filters that you can add there
is a filter on last activity.
So when was the last commit or pull request closed
or issue opened or something like that.
So how active is the project?
And Daniel suggested that we had a first activity filter
as well, so that you can start to filter packages
by effectively how old they are.
So you can filter to only packages that have been created
within the last year, for example.
Or you can say packages that are at least six months old
or something like that,
which is maybe a more realistic way to use it.
And so we had a little discussion on the discussion board
and that got transitioned into an issue.
And Daniel is on his way to producing that
as a pull request, which will get into the system
and add that functionality into the software,
which is great.
And then another contribution,
which is a little bit further along.
In fact, I think the final part of it
is going to be merged today,
which means it will be live on the site
by the time you hear this.
It's from Mirza Ucchanbalik.
And that is a feature that we had in our heads
since almost the very beginning of this project.
It's a three digit issue number,
which is pretty rare these days,
that this was originally there.
And it's to add some information on package pages
for packages that have been forked from
another Git repository.
And so what's going to happen is,
as of by the time you hear this,
you'll be able to, if a package is a fork of another package,
you'll be able to see that right at the top
of the metadata description on the package page.
And it will say this package is forked from
and then give you a link to the previous package.
And this is one of those features
that is really interesting because it sounds
much more simple than it is.
And it's one of those that has a couple of little edge cases
and it's been kind of interesting going through with Mirza
to find those and then decide what to do with them
and cope with them.
So the idea is a couple of these are like, for example,
the idea is that we could provide a link
to the parent package, of course,
that seems an obvious thing to do.
But then we have the choice of, well, what do we do?
Do we link to the GitHub repository?
Do we link to the Swift package index page?
In that case, what happens if the package
isn't in the index?
I think most of them are,
but we have to cope with those edge cases
where it might not be, or for some reason,
the original package author of the fork
wants their package removed.
And that the fork is now the definitive package
or something like that.
So you have this condition of, well,
what happens depending on where that repository currently,
where that parent repository currently is.
So that was kind of interesting.
And then you've got things like, well, what happens
if the parent repository is renamed
or the child repository is renamed?
And you've got all these kind of little edge cases
around a feature like this.
That something quite simple initially
can turn into a much bigger feature
than you might've thought it was.
But it's been great to work with Mirza on this.
And I think it's turned into a really great little feature.
And I'm really happy to see it ship finally,
because this is something that's,
well, this is something that tripped me up recently
that I thought I was talking about a package
and actually I was talking about a fork of a package.
And it is really useful.
There's nothing wrong.
I'm happy that we have forks in,
and I'm happy to have as many forks
in the package repository as can exist.
That's not the problem at all.
But the knowledge that you are looking at a fork
is really quite important.
- Yeah, exactly.
I'm really glad we're getting to this finally, so to speak.
And I actually was thinking about that as well.
I mean, I think that prompted it effectively, right?
Us revisiting that issue was the fact
that we ourselves were tripped up,
not realizing that the package is actually a fork.
- Yeah.
- Right, in other news,
there are a couple of important packages
we wanted to mention that have seen recent updates.
This is also server-side Swift.
So Hummingbird 2 has come out.
So the second version of Hummingbird.
I believe you also linked to this
in iOS Dev Weekly, didn't you, Dave?
- Both of them, yeah.
- Yeah, both of them, exactly.
Yeah, and Hummingbird 2 is out.
Beautiful webpage.
I want to give out a shout out to the webpage.
Looks fantastic.
Really, really nice to navigate.
Briefly, what's new in version two,
it's fully async/await.
So written with async/await in mind from the start,
and it is Swift 6 ready.
Give it a go.
I always, when I talk about Hummingbird and Vapor,
the other package that I'll mention in a minute,
to compare them, and this,
apologies if you don't know Python,
but in the Python world,
there's two packages that are Flask and Django.
And Django is the one where everything comes,
you pull in Django, you have everything,
and Flask is the one where you pull in a core package
and then you add things as you need them.
And that's how I think about when I compare
Hummingbird and Vapor.
Vapor's the one where you get everything off the bat,
and Hummingbird is where the one
where you're more focused and more diligent
about where you start and what you then pull in,
in addition.
- It's a really common pattern in the Ruby world.
There's Rails, which is the whole everything,
and then there's Sinatra,
which is the one where you start with the minimal
and then bring other modules in as you need.
- Right, yeah.
Yeah, and it makes perfect sense, right?
Sometimes, especially early on, maybe,
when you're learning a framework or a language,
it's nice to have something
where you don't need to worry about
finding the best thing to do, X.
You know, how do I do database?
And then you have to go hunting,
well, what's the package?
It's really great on those occasions
to have everything at the ready.
If you know your way around,
it's also nice to start small, right,
and not incur the build costs and all that,
and stuff that might be confusing
or might be in the way when you actually know already,
well, I'm not going to need that.
So it's really great to have the choice.
And as I mentioned, Vapor also hasn't had the release,
the next release, which is version five,
but they've put up a post about the future of Vapor,
and it's laying out the plans for version five of Vapor,
which is, it's very similar
to what Hummingbird 2 is really.
It's fully async/await,
using structured concurrency throughout,
and it's Swift 6 ready,
which isn't to say that neither of those
is the case for Vapor 6.
It's just that in Vapor 6, it is async/await ready,
so you can use it, and it's fully Swift 6 ready as well,
but the async/awaitness has been sort of retrofitted,
and in lots of places,
stuff has been made sendable via locks.
So as a user, as an API user, you wouldn't notice it,
but under the hood, I think you're going to,
if you're very performance sensitive, perhaps,
you would probably see that there's locking going on
under the hood,
but I think, and we've been using Vapor for years now,
and we've transitioned to async/await fully.
We don't notice any downsides of this right now,
but it's still nice to have the plan laid out,
and there's also a couple other things,
like moving to use a few more upstream packages,
like for instance, the HTTP types from the Swiftlang,
Swift HTTP types repository,
so there's, and that's going to make it easier
once you use these types as currency types to exchange.
If you have different packages that all use these types,
it becomes easier to exchange those types
because they then live in an upstream library,
so imagine you have a router that returns
some common HTTP type.
You can easily plug it into another component
that uses that same type without having to write
a little converter for that,
so that's really nice to see.
The first alpha should be released really soon.
In fact, it might be released already.
I haven't seen it, but I might have missed it.
I didn't go actively looking.
It certainly should be imminent,
perhaps around the conference end of this week,
or maybe shortly after.
You should see the first beta of Vapor V.
- The only other thing I'd add there
is I think I should add some clarification
on version numbers because there were a lot of Swift 6
and Vapor Vs and Homebird 2s and Vapor 4s in there,
and I think you may have got the numbers mixed up
a little bit, a couple of points.
- Oh, did I?
- Yeah, so you were talking about Vapor 6,
which is not a thing.
That's Vapor V.
- It will be, though.
It will be, I'm sure.
(laughing)
- Yeah, so that's Vapor V with Swift 6 support,
and Hummingbird 2 also with Swift 6 support.
- It's, you know.
- Just to clarify that.
- I was 18 on the iPhone 17, right,
and running on MacOS, oh God, it's all so terrible.
- Exactly, yeah.
And the Swift package index is still on version 2
and has been for the last three and a half years.
- Yeah, but for a minor version 101.
(laughing)
So yes, lots of version numbers.
We shall, as an industry, we shall one day solve
the mystery of how to do version numbers.
- Oh dear.
- So should we do some package recommendations?
- Let's do some packages.
Do you wanna kick us off?
- Sure thing.
I'm gonna talk first about a package called Swift Snowflake
by Jaehong Kang, and this is,
so I hadn't actually come across the idea
of this Snowflake ID.
Had you?
Do you know about a Snowflake ID?
- No, it sort of rings a bell.
I might've read about it, but I can't recall any details.
- Right, okay, yes, it might, yeah.
You probably will have heard something about it,
or at least there are lots of technologies
which I'm sure you do know.
Like for example, UDIDs are a similar,
solving a similar problem to this.
A Snowflake ID in best Wikipedia terminology
is a form of unique identifier
used in distributed computing.
It was initially created in the early days of Twitter
and used for the IDs of tweets,
but now it's used by Masterdard, it's used by Instagram,
it's used by Discord,
it's used by a whole load of other products.
And it is a kind of guaranteed unique number
that an individual machine can generate
without needing to know what the previous number was.
So 64 bytes binary, it starts with a timestamp,
it then has a machine ID,
and then has a sequence number for that machine after that.
And a little bit like UUID or UD-
- UUID?
- No, UDID is unique device, isn't it?
And UUID is universally unique.
Yes, you can then generate these numbers
which are good for, maybe you can use them as database ID,
but you can certainly use them for public identifiers
for unique resources inside your application.
And Swift Snowflake is a implementation
of Snowflake IDs for Swift.
So it's very, very simple to use.
You can either represent a specific Snowflake ID
if you would like to represent one that you already have,
or you can ask it to generate one.
And there are various different strategies
for encoding that if you want to put it into JSON.
And yeah, it's a very, very simple package to use,
but I hadn't come across the Snowflake IDs before,
and I thought they were kind of interesting.
- Interesting.
Just to clarify, you said 64 bytes.
Did you mean bytes or bits?
- Bits, I meant bits.
Like it's like Vapor 6 and 64 bytes.
Yeah.
(laughs)
Yeah, a 64 byte identifier would be amazing.
That would be more identifiers
than there are grains of sand in the world, I'm sure.
- Yeah, that's for sure.
But also, I mean, UUID is 128,
and that is, that bears, I mean, it's a small risk,
but there's a risk of collision.
You said guaranteed unique.
I mean, and that's half the size, I guess, that-
- Probably.
There is no mention of the word guaranteed unique
on the Wikipedia page.
- Oh, okay.
(laughs)
- That is me projecting my wishes onto this forum.
- Okay, that's a wishful thinking addition.
It does say,
it does say, I mean,
per machine secrets number two,
allow creation of multiple snowflakes
in the same millisecond, which is quite reasonable.
- Yeah, yeah, I mean, even with,
especially with UUID, the chances are really, really slim.
I mean, if you think your problem is a UUID collision,
then in all likelihood, you need to think again,
if that was really what's happening.
- Right, yeah, exactly.
Yeah, yeah.
And I think maybe that's the place to think about this
rather than maybe a UUID,
which is if it tends to be used for
identifiers that might end up in like a URL.
So where a UUID might be a little bit long for a URL,
this is a little shorter
and might fit into a URL more conveniently
than some of the longer identifiers.
- Yeah, yeah.
Plus also not always,
there are scenarios where you can think
you might need an ID.
And if, I mean, even in the remote chance
that there is a collision, it might not be fatal, right?
You might be able to detect and just regenerate.
You know, that's also sometimes an option.
- Right.
- Uh-huh, interesting.
Nice.
Right, my first pick is called Versionator by Sam Dean.
And that's a nice little package.
It's a build plugin that generates a source file
with version control info.
So I think that's quite a common scenario.
And I even thought we talked about a package
like this before,
but I didn't find anything in the show notes.
So if this is a repeat mention of a,
not this package in all likelihood,
but a similar package, apologies.
But this covers the scenario where you have an app
and you want to expose version information
that is, you know, like what git hash
did generate this build, that sort of thing.
And you don't want to automatically,
you know, don't want to manually track that version number.
This plugin will generate a source file
that you can use and reference in your application
and then, you know, display it and whatnot.
It has a number of different things in the struct
that it generates, like for instance, the build count.
And this is using git under the hood
to determine these values.
So it counts the number of commits since the start.
So that's a good thing to use for build count.
The git commit, as I mentioned, the hash, the shah.
And it can generate a git describe string.
So that's typically the tag,
but it can also include additional information
if you're not exactly on a tag, it'll add some extra info.
It's really nice, you just stick that in there
and you get this source file that you can then use.
It's a bit like in the old days,
which doesn't work with git anymore,
but in older version control systems,
you could place special tags in your source code
that would be replaced by the version control system
whenever you made a commit.
CVS, if people old enough to know CVS
will know the little dollar.
I think it was $CVS$ that you put in your source code
and it replaced that under the hood.
So yeah, that's Versionator by Sam Dean.
- Fantastic.
My next package is Game Controller Kit by Wesley de Groot.
And this is predictably a package
that allows you to easily interface with game controllers
on lots of platforms,
iOS, macOS, VisionOS, tvOS.
No support yet for watchOS,
which I'm terribly disappointed about
because I desperately want to.
Actually, how would you hold the controller
and look at your watch?
Maybe that's why it doesn't support watchOS.
(laughs)
- You got there eventually.
- But...
(laughs)
It was only as I actually looked at my watch
and realized the difficulty that would cause.
So we'll forgive the lack of support for watchOS.
But yes, what it is, is it's a package
that really gives a nice, convenient programming interface
to a game controller.
Both the detection of button events and joystick events,
but also control of the haptics.
So most, if not all game controllers
have pretty sophisticated haptics these days
and you get control of...
I actually can't see at what level
you get control of the haptics,
but it does say that you get control of the haptics.
So that may just be as simple as, you know,
give it a vibrate,
or it may be something a little more subtle
like we have on the iPhone.
But yeah, I thought this was just a very,
really super simple way to get access
to an input device that you may not be thinking about
at the moment.
Comes with a demo app that for the iPhone or for the Mac,
or there's also a tvOS screenshot here,
which I guess is a great platform for game controllers
where it has every input and button mapped out
onto the screen, including things like the touchpad.
So I think it's the PlayStation controller has a touchpad.
All the trigger buttons, all the left, right, up, downs,
the X, Y, A, Bs,
and of course the two joysticks as well.
So it seems like a great and comprehensive library
to get access to that.
Should we add game controller support to SwiftPackage Index?
Is that something that people are crying out for?
- That's a tough sell, but who knows?
Maybe open a discussion first.
- That's a very polite way of saying no.
- That's a standard way of dealing with feature requests.
- Yes, please put it in a discussion.
So yes, that's a game controller kit by Wesley de Groot.
- Nice.
Right, my second pick,
I was going to snipe you in iOS Dev Weekly,
but then because we pushed it back by a week,
you actually sniped me.
And the package is called Swift Export by Frank Lefebvre.
And it's a package, it's a command line tool
to make it easier to sign and authorize executables
on macOS.
And that sounds like a great tool to help with this.
So it's been a while that I actually
redeployed my app or our SPI app.
And what I normally do, I've sort of written down the steps
that I go through in Xcode,
you know, like clicking through dialogues.
But I always love having something that I can make file
or a script that I can run that sort of encodes the steps
in like actual code that I can check in
because I can never, like a few months later,
I don't remember how to release things.
And I would absolutely use this and change this
and use this to notarize an executable
because I could then put it in a script.
So this is really nice way of automating that
and dealing with this sort of, yeah,
taking out the dialogue based distribution.
Yeah, so that's Swift Export by Frank Lefebvre.
- I believe, so I did link to that in our Dev Weekly.
And I believe it also has some extra features
like it can automate the generation
of a package-based installer.
So a .pkg file, which if you, yeah,
if you need to do additional things like, you know,
move files into places that are not just
in the applications directory, for example,
you can again automate and create a configuration file
to perform those steps as part of the installer.
And it will then generate that package installer as well.
I think as long as I didn't get it mixed up,
but I believe that's the case.
- That's great, I didn't even notice that.
That's fantastic.
- Well, I think probably because we're not going to need that
with the SPI app, because that is just a pure, simple copy
into the applications directory and you're done.
But yeah, it reminds me of the old,
and this is going back a long time now,
the old install shield.
Did you ever have to use install shield on Windows?
- Oh God, yeah, yeah.
I mean, it's still, they still run installers, right?
- It is, yeah, yeah.
It does still exist.
And I believe it still makes package,
installer packages for Mac OS, I believe.
But it's certainly, it's a bit of a,
I think it's a bit of an old technology now of that whole,
well, let's build our installer.
But certainly this would be a simpler way of doing that
than some software like that, I'm sure.
Maybe I'm being terribly unfair to install shield,
but I somehow doubt it.
- Nice.
- My final package this week is a little bit of a fun one.
I like to occasionally include a fun package
in the recommendations here,
and it's called Chip8i Emulation Core by Danijel Stracenski.
And I also hadn't heard of the Chip8 system,
which is, again, an old,
it's an old microprocessor originally used
on the Cosmac VIP and Telmac 1800
that were 18, eight-bit microcomputers in the,
from the '70s.
And what it is, is it's a swift emulation
of the, that whole processor.
So what you get as an API from Swift
is a way to load ROM files in.
So you don't get to code in the basic
or whatever the language of the thing had.
It just enables you to load the ROM files in.
And then you get to call this emulation function,
and it has 16 input keys, which, again,
so it didn't even have a full keyboard.
It had one, zero to nine numbers,
and A to F, so it could input hex, I guess,
is effectively what it could do.
And then you get to hook into various key presses.
So you can say on key down or on key up on any of the keys.
You can observe the output.
You also get a 64 by 32 grid of Boolean values,
which represent the pixel states on the screen.
So it was a very high resolution display,
which you could then represent in SwiftUI
or whatever technology you would like
to represent those pixels as.
In fact, there is an example in the readme file,
which is a Mac OS SwiftUI app that generates CG images
and lays them out on a SwiftUI display
based on this 64 by 32 bit grid of Booleans.
So it's kind of interesting that something like this
would end up emulated in Swift,
but I thought it was an interesting thing
to have a quick look at.
- That's amazing.
Actually, if you think about it, as you were talking,
I was looking at my watch and I thought,
well, this is a tiny piece of a complication on my watch.
(laughs)
- Exactly.
Yeah, I mean, 64 by 32 is really low resolution.
It's like super low resolution.
- Yeah, but it's not that far off where we started.
But my first computer was the Commodore 64,
and I think that was 320 by something or 480 by 320,
something like that.
It wasn't that much more.
I mean, a little bit more, but-
- No, not that much more, yeah.
- Not way more.
So yeah, really fun.
- So you could take a little trip down.
It's probably not exactly a trip down memory lane
because I'm not confident that many people
will have used this system listening to this podcast,
but it's always fun to look at
a bit of the history of computing.
- Yeah, absolutely.
Right, my third and final pick is called Spectricate
by Patrik Svensson.
And can I just say, great last name, Patrick.
(laughs)
The package is a library to help you
create beautiful terminal applications.
I think that's a quote I lifted from the package.
And just look at it.
If you open that up and look at the screenshot
that Patrick has placed there of a table,
a panel and a table created with it, it's just fantastic.
We had a couple of packages
to create terminal applications in the past, I believe.
And I always pick them.
So if you want to get mentioned,
I think that's a package you sort of need to create.
But it's just beautiful.
I think the UI is Swift UI like,
but even if it isn't, just look at the result.
You'll implement this with any API,
I think, to get results like this.
I recall having written a little tool
that deals with our ProSquare database in the past.
And I was looking around for packages
that output nice table views, like tables in the terminal.
And I'm very sure that that hadn't existed at the time
because I would have certainly picked it.
But it kind of makes me want to go back
and substitute that one in now.
- Yeah, I just had a look at it and it looks great.
It's really, I quite like the kind of curved edge boxes
as well as the straight edge boxes.
Is that using, they're not characters.
Are they being drawn or are they characters?
- Yeah, those are, so all these use Unicode glyphs
to generate the tables.
So this would be fully selectable and pasteable.
I mean, obviously you'd have,
you wouldn't get just the text,
you'd get the text and the Unicode stuff.
So it'll, formatting might change if you have a non,
you know, a font that doesn't support all the glyphs
or if you paste this into a proportional font thing,
then it would be messed up.
But no, it is proper text.
- I'm very familiar with the single and the double boxes
from back in the old DOS days.
But I haven't yet seen the boxes with curved corners before.
So that's news to me.
There are still characters in the Unicode character set
that I'm unfamiliar with.
- Yeah, it's beautiful, isn't it?
- That's, it is, yeah, it's great.
It takes me back to the days of Ball and IDEs
where they used the double box characters to great effect
to create all their windows and UIs.
Very fond memories of that.
There we go.
So that brings us to the end of another episode.
And if you are at the Server-Side Swift conference,
please do try and find Sven and say hello.
And if not, then we'll see you back here
in a few weeks time.
- Yep, see you in a few weeks.
Bye-bye.
- All right, bye-bye.