# F# Tip 4: When (not) to use point-free style

### Brian Berns ・2 min read

*Inspired by a blog post 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:

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

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

```
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" approach:

```
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:

```
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. 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:

```
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!