As I’ve been writing more F# code and learning more about the F# language, I have found myself intrigued by how some surprisingly simple language features can combine with each other to enable us to write very expressive code. While I am still learning F# (and realize just how much more I have to learn), I’m hoping that sharing some of these thoughts will encourage others to dig into what I think is a very powerful language that a lot of us developers can learn from.
In this post, we’re going to talk about Infix Operators. Before we dive into F#’s implementation of infix operators though, let’s discuss what an “Infix” Operator actually is.
So what is an “Infix” operator? An infix operator is an operator that is expressed using a mathematical notation called infix notation. When it comes to these types of mathematical notations, there are three primary kinds: Prefix Notation, Infix Notation, and Postfix Notation.
Take for example the addition operator. The addition operator takes two operands that are then added together. Using infix notation, the operator is written between the two operands it operates upon. Prefix notation would have the operator before the operands, and postfix notation has the operator after the operands. So given the addition operator, the different notations would like the following:
- Prefix notation: + 3 4 (definitely familiar to LISP-heads –> “(+ 3 4)”)
- Infix notation: 3 + 4 (familiar to most of us developers)
- Postfix notation: 3 4 + (an interest way used by Forth for one, a stack-as-first-class-citizen language –> “3 4 ADD”)
One of the things I love about F# is that infix operators are normal functions that you can easily define yourself. Let’s explore this concept a bit. Open up F# Interactive and execute the following command:
val it : (int -> int -> int) = <fun:clo@42>
Note: Surrounding the infix operator with “()” allows us to get at the underlying function that implements the infix operator, rather than the operator itself.
Heck, we can even call it like a normal function:
> (+) 3 4;;
val it : int = 7
You can see here that the addition operator is simply a function that accepts two integers and returns an integer (well, this isn’t technically true, but you can think about it this way for now; we’ll get into the difference in a different post). I said before we can easily define our own infix operator. How do we do that? Well, just for giggles, let’s go ahead and define our own add operator:
> let (|+) x y = x + y;;
val (|+) : int -> int -> int
After we define this function, we can use our new infix operator just like any of the other built-in infix operator:
> 3 |+ 4;;
val it : int = 7
Yes, it’s that simple.
Well, that’s a very quick look at a seemingly simple language feature that a lot of us developers tend to take for granted. In future posts, we’ll see how combining infix operators with other features in F# allows us to write more expressive F# code.