The Beauty of Hacking Swift: Make Union of Set Algebra Types More Obvious

I found it weird to form the union of two CharacterSet instances by calling the union method on one element:


This chains nicely, but what pops out to me looking at the line of code is the CharacterSet, then something about URLs, and then I scan the line to see what kind of statement this is – some lengthy stuff that looks like chained method calls at first glance due to the length and the many dots.

Instead, I prefer a static method/function:

extension SetAlgebra {
    static func union(_ sets: Self...) -> Self {
        guard let first = sets.first else { return self.init() }
        return sets.dropFirst().reduce(first) { $0.union($1) }

That way, I can write:

CharacterSet.union(.urlHostAllowed, .urlPathAllowed)

… and thus I can highlight the union operator in my code instead of bringing attention to the first set in the union. This gets even better when you add more sets into the union.

This is no segue to hate OOP and method calls. I think the traditional OOP style works fine for a lot of cases. But functions work better for some operator tasks. (I’m not ready to make this a generic free function just yet, but think it’s a sensible next step.)

This kind of customization is by no means ground-breaking. But it’s one of the things we can do in Swift that make working with Swift enjoyable. It’s the ‘hacking’ with the language. I don’t have to cook my own unionizing type, I can just amend the existing code a bit to suit my, well, tastes. Because functionally, the code is equivalent. And the reducer is probably harder to read if you don’t know how reducers work (hello past-me from 5 years ago!). But the surface API is much nicer and doesn’t require any arcane skills.

With recent events on my computer, this reminds me a lot of the hackability of Emacs Lisp and thus the editor I’m using to write this while it’s running, and of course Smalltalk and its IDE, and Ruby. It works differently, but it’s a similar kind of joy of hacking.