Logo 61e73bc61c0e1780102320e879dc3cac0e29303ea8894dd8f10c942f3ba8120f

otters.io

An adorable little blog

Custom Operators, The Stupidest Neat Feature in Swift

Tuesday — April 19th, 2016

Did you know you can overload operators and even make custom operators in Swift? Why would you want to? No idea. The obvious first thought for anyone who has tinkered around in C++ might be:

“I know! I’ll make my own equality operators for my custom types and classes!“

Smart

Before you get too excited. A better option might be to implement the Equatable and Comparable Protocols, which give you a standard way for doing just that.

Swift also allows you to make up your own operators for any type, which is something C++ doesn’t even allow (without hacky macros). As long as you use an approved unicode character you can make a custom operator!

Why should you do this? You shouldn’t. You definitely shouldn’t. Everyone you work with will hate your face. Your custom operators can 💀 in a 🔥 .

Why? In general, it obscures the meaning of the code you are writing. And I know that you’re probably thinking:

“I have a legitimate reason for making my own operators! You’re just putting straw-man arguments in blockquotes to make me feel like I shouldn’t use them! You’re such a lame-o, I’m going to use custom operators anyway. It’s so obvious what this line means. No one could ever be confused.“

Highfive

If you’re working alone or your co-conspirators can agree on a set of operators, custom operators could be of some use. I'm sure that you are a special snowflake ❄️ and have a perfectly good reason for needing custom operators. So here is how you could accomplish such a task.

First, you’ll need to decide if you need a prefix, a postfix, or an infix operator.

A prefix operator comes before the value being operated on. Like ++myVariable.
A postfix operator comes after the value being operated on. Like myVariable++.
An infix operator comes between two values. Like myVariable + 7.

Second, you’ll need to dig out your 5th Grade math textbook and read up on order of operations (PEMDAS) so you can decide what precedence your fancy pants operator will have. If you chose to make a prefix or postfix operator, you can skip this step. They get the highest precedence for free (Although, if you apply both a prefix and postfix operator to a value the postfix will always go first). Precedence in Swift is determined by a number value. The higher number, the higher the precedence.

Third, if you’re still stuck on making an infix operator you’ll need to decide on your operator’s associativity. Associativity is a version of the time-honored game “Who would win a fight…“. Associativity defines who wins when two operators have the same precedence value. Here is an example, “Who would win a fight of 2 % 3 * 4? Modulo or Multiply?“. % and * have the same precedence in Swift, but both are left associative. Meaning the equation should be read from left-to-right. So in that example, the modulo operator wins and the result is 8 not 2. The possible values for associativity are left, right, and none.

Finally, you’ll just need your implementation of the operator. I hope you have your mind made by this point.

So let’s make a really stupid example. Let’s say you wanted a +++ operator that added one value three times to another value. If you only used it for a single value, it can just add 3 to it. The end result might look something like this:

prefix operator +++ {}
prefix func +++ (n: Int) -> Int {
    return n + 3
}

postfix operator +++ {} 
postfix func +++(n: Int) -> Int {
    return n + 3
}

infix operator +++ { associativity left precedence 155 }
func +++ (left: Int, right: Int) -> Int {
    return left + right*3
}

So now, if you write 1 +++ 2 you’ll get back 10. Just another warning, the above code works fine in a Swift 2.2 playground but produces some interesting results in the Swift 2.2 command-line REPL. Another great reason to think twice.

Again, don’t get too antsy. I know what you’re thinking:

“Swift 3 is removing the ++ and -- operators? I’ll just make them myself with custom operators!“

You’ll have to decide for yourself if it’s worth staying in the past for such a small thing. You can read Chris Lattner’s Pro/Con list on the Swift Evolution repo for why you might want to move forward with the rest of the herd.

Just to reiterate, please don’t use custom operators. 😊