Refinement Types for Swift

On 21 March 2019 I gave a lighning talk about Refinement Types at NSBarcelona‘s Universal links, Deep Linking and Routing @ Inqbarna HQ event.

I started the talk with a quote from Tony Horare:

I call it my billion-dollar mistake. It was the invention of the null reference in 1965. At that time, I was designing the first comprehensive type system for references in an object oriented language (ALGOL W). My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn’t resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years.

Null References: The Billion Dollar Mistake

And then, another one from Robert C. Martin (Uncle Bob):

The question is: Whose job is it to manage the nulls. The language? Or the programmer?

These languages [Swift and Kotlin] are like the little Dutch boy sticking his fingers in the dike. Every time there’s a new kind of bug, we add a language feature to prevent that kind of bug. And so these languages accumulate more and more fingers in holes in dikes. The problem is, eventually you run out of fingers and toes.

The Dark Path

After those contrast views on how to develop software, I explained an experiment I was conducting on how to implement Refinement Types in Swift.

If you feel curious, you can check the slides here.

Type transparency

At the moment of preparing the slides, I was experimenting on making refined types and their base types interchangeable.

In the past, I had developed swift-sourcerer, a proof-of-concept metaprogramming framework based on Sourcery. And I thought I could use it along with GYB to generate the boilerplate code required to achieve type transparency for refinement types.

As a result, I created 2 repositories, Wrapper and Features, that could be used to make refined types more interchangeable with their base Swift types.

Fluent DSL

Lately, however, I have been more focused on defining a DSL to work in a more convenient way with refinement types.

Initially I was using simple typealias to make code more readable (e.g. String.NonEmpty instead of Refined<Not<Empty<String>>>).

It was an improvement, but it fell short in terms of combination of predicates (String.CountMoreThanTwo, String.CountLessThanThree, etc.).

For this reason I decided to use a GYB template to autogenerate more complex typealias that allow to combine different predicates in a fluent interface fashion.

See some examples:

String.Count<Int_Four>.Or.Empty("")     // is valid
String.Count<Int_Four>.Or.Empty("1")    // is invalid
String.Count<Int_Four>.Or.Empty("12")   // is invalid
String.Count<Int_Four>.Or.Empty("123")  // is invalid
String.Count<Int_Four>.Or.Empty("1234") // is valid
Character.Letter.And.Lowercase("a") // is valid
Character.Letter.And.Lowercase("0") // is invalid
Character.Letter.And.Lowercase("A") // is invalid

Or clone the repo and try it out yourself. 😉

Object-Oriented Programming vs Functional Programming

Yesterday I read the article Object-Oriented Programming — The Trillion Dollar Disaster.

It is incendiary. The sort of material written to go viral. But it is also reasoned and brilliant. I recommend it to everyone. Even to the most fervent defenders of OOP.

Subtitle already leaves it clear: "Why it’s time to move on from OOP". Well, you don’t need to agree with the conclusion to enjoy reading the article. And no one can deny how much truth there is everywhere in the text. See for instance the section The Problems of State (my personal favorite).

The author, Ilya Suzdalnitski, not only reviews the major Object-Oriented Programming flaws. He also praises Functional Programming. And that is for me the weakest part of the article.

I liked the citations (anything gets better adorned by a Dijkstra quote).

I loved the concepts exposed (e.g. Law of Demeter, Domain-Driven Design, etc.).

But… the emphasis in the intrinsic evilness of OOP and how FP is the solution. Meh. It reminds me to the old my language is better than yours debate.

And then, there’s that line that reads like: "With the right guidance and linting, JavaScript can be a good functional language". I don’t feel qualified to comment on that, so I will not.

All in all, a great article every OOP programmer should read.