How to create a custom operator (like ~= operator) in swift ?? — 🤓🤓🤓🤓

I have seen developers using custom operators which adds meaning to the code and reduce the amount of code required to perform an operation. Creating custom operators are not encouraged. But you still can, if you wish to!!.

Image for post
Image for post

I was learning about pattern matching in swift and my eyes got stuck on a special operator ~= . I have used this before for pattern matching, But I didn’t knew how it works. I have used ~= operator for checking if the http error fall into any of the given range (wanted to check if error is 4xx excluding 401) like this:

Image for post
Image for post

I didn’t had any idea what it does internally. I also didn’t knew that we can also create custom operators like this. So, I asked google about this and he showed me all what I wanted.

Have a look at some of such operators in swift: Defines Swift

Types of Operators

Operators in swift fall into the following types:

  • Infix — Used between two values (ex: <value>+<value>)
  • Prefix — Used before a value (ex: !<value>)
  • Postfix — Used after a value (ex: <value>!)
  • Ternary — Two symbols inserted between three values(ex: <value1> ?<value2> :<value3>). We cannot create custom ternary operators as of now. Swift won’t allow developers to do this.

How to create Custom Operators??

Let’s create a custom operator for finding the square root of a number using the symbol.

Note: We already have the sqrt() function to find the square root and is easy to use. Consider this as a simple example to create custom operators🤓🤓 .

We should be using this as a prefix operator like:

let someVal = 25let squareRoot = someVal // result is 5

Let’s discuss the steps to create one.

  • We need to declare this symbol as a prefix operator.
prefix operator √
  • We need to create a function which accepts one parameter and perform the operation (square root).
prefix func √(lhs: Double) -> Double {return sqrt(lhs)}

DONE!! — — — Congrats!!. You just created a custom prefix operator to find the square root.

Image for post
Image for post
Custom square root operator in swift

Let us create a custom infix operator using ◉ symbol.

The ◉ operator function will accept two values lhs and rhs and return the sum of squares of these values. ie; if lhs is 2 and rhs is 3, the result will be 4 + 9. ie; 13.

If you remember the steps,

  • We need to declare this ◉ symbol as a infix operator.
infix operator ◉
  • We need to create a function which accepts two parameters and perform the operation explained above.
infix func ◉(lhs: Double, rhs: Double) -> Double {return lhs * lhs + rhs * rhs}

If you do this, the compiler will yell at you saying: error: MyPlayground.playground:14:1: error: ‘infix’ modifier is not required or allowed on func declarations

So, rewrite the function by removing the infix keyword.

 func ◉(lhs: Double, rhs: Double) -> Double {return lhs * lhs + rhs * rhs}
Image for post
Image for post

Congrats. You just created a custom infix operator. But wait. Is that it??🤨🤨

Answer: YES 😱😱😱 !!!.. Almost forgot the operator precedence that we learned in school.

Refer pages: Order of operations,Operator declarations.

In mathematics and most computer languages, multiplication is granted a higher precedence than addition. Thus, the expression 2 + 3 × 4 is interpreted to have the value 2 + (3 × 4) = 14, not (2 + 3) × 4 = 20. We will have to consider this as well while creating a custom operator. The operators precedence is an important factor.

Precedence and Associativity

Apple Docs Link here.

Operator precedence gives some operators higher priority than others; these operators are applied first.

Operator associativity defines how operators of the same precedence are grouped together — either grouped from the left, or grouped from the right. Think of it as meaning “they associate with the expression to their left,” or “they associate with the expression to their right.”

Types that have a left associativity are parsed so that v1 + v2 + v3 == (v1 + v2) + v3. The opposite is true for right associativity.

If you declare a new operator without specifying a precedence group, it is a member of the DefaultPrecedence precedence group. DefaultPrecedence has no associativity and a precedence immediately higher than TernaryPrecedence.

Image for post
Image for post
Source: raywenderlich

Refer Apple docs to get the entire list of operators used in swift with their details.

Coming back to our ◉ infix operator, It doesn’t fit to any of the standard precedence groups. We will have to create our own. How to do that?

  • Create a precedence group called SquareSumOperatorPrecedence.
precedencegroup SquareSumOperatorPrecedence {lowerThan: MultiplicationPrecedencehigherThan: AdditionPrecedenceassociativity: leftassignment: false}

Here, we created a precedence group with precedence higher than AdditionPrecedence and lower than MultiplicationPrecedence and left associativity.

‘none’, ‘left’, or ‘right’ are the possible values for associativity.

The assignment modifier that works as follows: an operator marked assignment gets folded into an optional chain, allowing foo?.bar += 2 to work as foo?(.bar += 2) instead of failing to type-check as (foo?.bar) += 2.

This behaviour will be passed to assignment: true on precedence groups.

  • Now replace your original declaration of the ◉ operator with the following:
infix operator ◉: SquareSumOperatorPrecedence

That’s it.

Image for post
Image for post
custom infix operator

That’s it. !

Where to go from here?

  • Learn about operator overloading.Classes and structures can provide their own implementations of existing operators. This is known as overloading the existing operators. Ex: == , + etc..
Image for post
Image for post
Example from apple docs
  • Learn more about adding generic type constraints to custom operators
Image for post
Image for post


You can follow me on Medium for fresh articles. Also, connect with me on LinkedIn and Twitter.

If you have any comment, question, or recommendation, feel free to post them in the comment section below!

Written by

iOS and tvOS developer, dreamer, photographer 🤨

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store