◀ Home

Namespaces in Swift Using Lowercase Enums

Problem

The implicit member expression syntax is common in modern Swift. It is common to have centrally-defined, statically-accessible constants and factories. At scale, it can become difficult to maintain coherent collections of these values without organization, especially with domain-agnostic types like TimeInterval (i.e. Double). Swift does not provide first-class support for namespaces.

Solution

Extend the type you want to add namespaced symbols to with a lowercase enum. Define symbols that are of the type that is being extended.

This gets us implicit member expression syntax at call sites that looks appropriate because of the lowercase type name. The values we can select are automatically scoped to those in the namespace. Set up and maintenance are straightforward with minimal misdirection; the caseless enum communicates that it cannot be instantiated. No extra instantiation takes place.

e.g.

extension TimeInterval {
    public enum animation {
        public static let `default`: TimeInterval = 0.25
        public static let minorTweak: TimeInterval = 0.15
        public static let pop: TimeInterval = 0.35
    }
}
UIView.animate(withDuration: .animation.default) {
    view.layoutIfNeeded()
}

Additionally, in most syntax highlighters, type names are different colors than other symbols, so the namespace has a visual affordance that helps us distinguish it from other symbols.

The lowercase type name goes against Swift name conventions and may be controversial. It is up to the reader to decide what is worth exposing to their audience.