One of the most debatable Swift features is the possibility to create your own (or overload the existing) operators. This feature has both pros and cons – on one hand you can make your code more readable, by getting rid of some verbose stuff. However, on the other hand, you might not implement the operator properly and make a complete mess. Also, others looking at your code might be confused about this new unknown operator. So, creating operators in Swift should be done with caution and only when needed.
One operator that I find really useful in projects is the Forward Pipe operator. First defined in F#, this operator helps us avoid multiple nested function calls. Let’s see how we can do this and see some examples.
Creating a custom operator in Swift is pretty straightforward.
First, we need to define the precedencegroup. This basically defines the priority of an operator, over other operators. With the higherThan property, we are defining a bigger priority than the LogicalConjunctionPrecedence (this is the Logical AND). The associativity defines how the operators that belong to the same precedence group are combined together – whether from the left or right. In our case, we are combining them from the left, since this is a forward pipe.
Next, we define the operator, which similarly to F#, has the |> syntax.
Finally, we are defining the function that this operator will have.
As you can see from the signature, it has two generic types, one for the input parameter and one for the return value. The input parameter is passed as an argument, along with a function that converts the input value to the value of the return type.
And that’s everything we need to do to have our own forward pipe operator. Let’s see this in action. Imagine, we have an image and we need to perform some operations on it. Without the forward pipe, that will look something like this:
Now, imagine you need to perform a lot more operations with the image. You will easily get lost with all the function nesting. Other possibility is to define variables for every function call, but with that approach you can end up with lots of unnecessary lines of code. If they are variables, there’s always the risk that someone might modify them when that’s not intended.
With the forward pipe operator, this is much cleaner:
Much nicer! How this thing works? The result of the first call is directly passed to the second one and so on. The last one gets the result from the one before and converts it to the final result.
With this approach, you don’t expose the states of the variable in every function call. You just get the final value, similarly to the Unix pipe. You can create as many functions as possible and combine them in different ways. Removing any function from the pipe is pretty easy. Imagine doing that with nested calls or in-between variables.
Let’s see another example. Imagine you have a request, and you need to extend its functionality with additional headers or parameters.
This is fairly simple and you can use the same approach on all different types of requests. If some other REST endpoint requires, let’s say, only two of the three listed and another endpoint different two, you can compose them in any way, reusing their functionality.
And that was the forward pipe operator. I find it very useful and I use it a lot in my projects. Are you also using it? What other custom operators are you using?