F# Tip 4: When (not) to use point-free style
Tags: fsharp, dotnet, functional
Published: 2020-01-06 17:29:13

*Inspired by a [blog post](https://eiriktsarpalis.wordpress.com/2017/04/02/programming-in-the-point-free-style/) by Eirik Tsarpalis.*

Let's write a small F# function that safely takes the square root of a number. Both the argument and the result should be wrapped in an `Option`, and the function should return `None` when the argument is `None` or negative. Something like this:

```fsharp
let safeSqrt (xOpt : Option<float>) : Option<float> =
   // implementation?
```

How would you implement this function? One approach is to use "bare-metal" pattern matching:

```fsharp
let safeSqrt xOpt =
    match xOpt with
        | Some x when x >= 0.0 -> sqrt x |> Some
        | _ -> None
```

That's easy to understand, but a bit verbose. Personally, I'd get tired quickly reading a lot of functions in that style. Let's try the opposite extreme instead, using a totally "[point-free](https://stackoverflow.com/questions/944446/what-is-point-free-style-in-functional-programming)" approach:

```fsharp
let safeSqrt =
    Option.filter ((<=) 0.0) >> Option.map sqrt
```

Well, that's certainly shorter, but is it actually better? It's not clear that `safeSqrt` is even a function any more, because it doesn't have an argument. Is there perhaps a middle ground?

`Option` comes with a bevy of composable higher-order functions (like `filter` and `map`) that every F# developer should be comfortable with, so it makes sense to use them instead of low-level pattern matching. However, having an explicit argument to the `safeSqrt` function helps a lot with readability, because it gives the function a "protaganist" that we can follow. The function then becomes a story about transformations applied to that protagonist. So with that in mind, here's another version of the function:

```fsharp
let safeSqrt xOpt =
    xOpt
        |> Option.filter (fun x -> x >= 0.0)
        |> Option.map (fun x -> sqrt x)
```

This approach makes it clear that our function is a good citizen of the `Option` monad. We can easily trace the adventures of `xOpt` as it moves through the steps of the function via the [pipe operator](https://dev.to/shimmer/f-tip-2-use-the-pipe-operator-2i2j). In particular, I think `fun x -> x >= 0.0` is a lot clearer than `(<=) 0.0`. In fact, the latter looks like it could mean "numbers that are not positive" when it is in fact the opposite. On the other hand, `fun x -> sqrt x` seems a bit wordy when we could just use `sqrt` point-free:

```fsharp
let safeSqrt xOpt =
    xOpt
        |> Option.filter (fun x -> x >= 0.0)
        |> Option.map sqrt
```

To my eye, this last version is the best because it uses higher-order functions with both lambdas and point-free functions where appropriate.

With this result in mind, here are some guidelines to keep in mind when trying to write clear, idiomatic F# code:

* Consider replacing raw function composition (`>>` and `<<`) with pipe operators (`|>` and `<|`) in order to give the input an explicit name.
* Avoid currying infix operators, such as `<=` and `>=`, especially when it means flipping arguments unnaturally. Use lambdas instead.
* Go ahead and use simple one-argument functions (like `sqrt`) without points in order to shorten code.

What do you think? Are there other guidelines you prefer? Let me know in the comments!