ProgrammingSwift middle/senior developer or framework architect

What are the nuances of implementing custom operators in Swift, how to properly declare infix/prefix/postfix operators, and where should they be applied?

Pass interviews with Hintsage AI assistant

Answer.

Background of the Question

Swift traditionally pays great attention to syntax clarity and allows for the creation of custom operators (operator overloading), including new symbols and even keywords. This expands the capabilities of DSL and allows for very expressive code.

Problem

Without understanding the principles of operator declaration, one can produce ambiguous, poorly readable, and hard-to-maintain code. Incorrectly chosen precedence or associativity will lead to unexpected results. The compiler allows creating quite "dangerous" expressions if restrictions are not specified.

Solution

You can declare new infix, prefix, postfix operators, specify their priorities, and areas of usage. Example:

infix operator ~> : AdditionPrecedence func ~> (lhs: Int, rhs: Int) -> Int { return lhs * 10 + rhs } let x = 2 ~> 3 // 23

For custom priorities, you need to declare:

precedencegroup MyPrecedence { associativity: left higherThan: AdditionPrecedence } infix operator *** : MyPrecedence

Key features:

  • Everything is declared at the file level (globally),
  • Priority, associativity, and direction can be finely tuned,
  • Should be used CONSCIOUSLY! In production code, abusing custom operators is evil.

Tricky Questions.

Is it mandatory to implement both a function and an operator declaration?

Yes, if you declare an operator, you need to implement the corresponding function - otherwise, it will result in a compiler error. Functions have a signature that matches the operator signature.

How to correctly choose precedencegroup, and how does it affect computation order?

precedencegroup specifies the computation priority and associativity for infix operators. An incorrect choice of group can lead to unexpected results in expressions with multiple operators (e.g., multiplication/addition and your custom operator).

Can a custom operator be declared with a text name?

No, custom operators are only available through special symbols or sequences defined by Swift's syntax. Text standard names are not allowed for operator declaration.

Common Mistakes and Anti-Patterns

  • Using custom operators for mundane tasks where a function is more readable,
  • Defining operators with non-obvious behavior,
  • Neglecting to declare a precedencegroup (leads to unpredictable behavior),
  • Copying symbols from Unicode that are unsupported in all fonts/IDEs.

Real-life Example

Negative Case

In the project, operators <<< and >>> were declared for strange transformations of collections, without description of priority, associativity, and documentation. New employees did not understand what they were doing and in what order the expressions were evaluated.

Pros:

  • Concise syntax

Cons:

  • Decreased code maintainability and readability
  • Errors in priority in complex expressions

Positive Case

In the project, a custom operator => was used for declarative assembly of a chainable pipeline (for example, in a UI builder), with a clearly described priority and documented implementation. Every developer understood what they were doing and how it was used.

Pros:

  • Increased expressiveness of DSL/chainable patterns
  • Easy to maintain and document

Cons:

  • Harder to debug unusual expressions
  • May deter new team members without documentation