Decentralized Package Management

One thing that has always given me a more favourable view of Swift is how Apple choose to go about handling package management from the very beginning. Similar to Go, the majority of packages are referenced using Git repositories. Swift differs in that you usually have to specify a snapshotted version using the tag feature instead of pulling everything from a certain branch. Not that you can’t do that, don’t get me wrong, it’s just not recommended in production.

While this method is not without its drawbacks, it does eliminate a lot of security concerns. Plenty of my toy Rust and .NET applications had relied on dependent bot to frequently update varies dependencies. Swift takes this approach a step further by having a minimum version baseline. You can really fine-tone this by simply updating every minor patch or major release. 

Really the biggest drawback is that you are building a lot of external dependencies all at once. Sure it removes DLL hell but it does increase the build time and processing resources by quite a bit. Trade offs. It’s essentially bad with languages like Rust because it exists in such weird middle ground between bare bones and having a feature complete standard library. Like, I had to write an extension for a time and date library just so I can get basic support for printing ISO weeks that I could use for my little toy program that was inspired by Tom Scott. I just created DLC for DLC just so my silly little program worked. Like, WTF!? Luckily, Swift isn’t that bad since Foundation is built into the language, regardless of the platform you’re on, and you know they’re going to optimize the shit out of it for experience. But I digress. xD

All that being said, this is how it’s always been done. Many C/C++ programs bundle libraries needed to successfully build their project. It’s basically why many of their classic projects have such big and monolithic repositories. When Git came along, plenty of new projects pulled from submodules instead. Even older .NET applications did this before NuGet came along. Modern programming languages, such as Go and Swift, just adopted a form of this submodule practice by baking it into the package manager and having those be referenced from a cache instead.

Really the biggest benefit is decentralization. Even if Apple attempted to were throw a wrench into the ecosystem, they’d likely miss. The majority of that ecosystem is just open source Git repositories that anyone fork. This is also means that you’re not limited to a central repository or host. Like, there is this one library I discovered a few days ago in the Swift Package Index they recently moved from GitHub to their own personal Git and it still functions all the same.

Compare this something like .NET, where everything is centralized on NuGet. While this isn’t necessarily a bad thing and it has certainly help evaluate the platform, Microsoft really has their grip on the wheel. All their recent .NET talks is just about AI this and AI that. Meanwhile, Apple is over here creating new open source libraries and features. Like the recent @c annotation that exports functions as C headers or their new Configuration library. I love the .NET guys. I really do. The two Scotts are my favourite. I just hate the leadership. (Not that Apple is any better.)

From Rust to Swift

As the Rust programming language continues to spread through the open source community, I find myself wanting to leave it. I haven’t touched it since the pandemic. The borrow checker is just so annoying to use. Like, the compiler could hit on you upside the head for the most benign things. It’s so frustrating. xD I’ve yearned for something that was just as safe without sacrificing damn near everything. My first attempt was with Zig and, as much I really liked it, the language still has some teething issues.

Now, I’ve been keeping track of Swift on and off for a long time. Roughly since it’s debut in 2014. Helps that I’m a Mac user. Despite suffering similar teething problems as Zig, it evolved rapidly and matured a lot since 5.0. I decided to give it another shot when I was setting up my Linux laptop. The RAM is very small by today’s standards so putting something like Rust’s complicated build system wasn’t much of an option. So I created a series of command line applications after I discovered that’s what “tool” option meant. My first attempt was creating a simple program that generates a desktop entry for Linux. It was quite simple to make. Like, the whole program is roughly a 100 lines of code. (Although, if you focus on the actual logic portion, it’s probably way tiny.) And although I haven’t properly tested it on a distro yet, the dry runs are working flawlessly.

I have a number of other tools written in not only Rust but C# that could do with a proper rewrite. The most complex are written in C# while the simpler ones are in Rust. My most simplistic is a D&D dice roller. I had planned to add support for modifiers but my issue with the borrowing checker forced me to abandon it. On the C# side, my tool used to used to streamlines building an EPUB using Pandoc is slightly more complex.

I decided to start simple and rewrote that dice roller. While it shares a roughly similar architecture as the original, there are some notable differences that make the two incompatible. Like instead of typing in any number using the --roll option, you can specify “d2” to “d100” as argument and add an additional --modifier option that you can type a number into. This new version functions more like an actual dice roller you’d use in D&D or any other tabletop game and less like random number generator dressed up as a one. Next up is allowing for multiple dice to be rolled so you can create different builds.

All that being said, Swift is turning out to be a joy to develop for and I may use it to create more tools in the future. Regardless of what some people may say, programming shouldn’t be a chore to do. I stuck with C# and tried out Zig preciously because it didn’t punish me for programming the way I was taught.

And don’t get me wrong, Rust is a great programming language. Once you get the hang of it, it is powerful tool to use like anything else. Rust has earned its spot to be adopted into the kernel and other Linux distros. The language was designed to handle loads like this. But it isn’t for me anymore.