Along the way there have been a few things that completely blew my mind, or that I thought were just flat out neat. You could (and should) learn about these things from much better sources, but I love to share!
So to kick it off, this first post will cover the first thing in F# that really truly blew my mind: the Pipe Forward operator. You see it used in F# all the time, and what it allows you specify the last parameter's value first, thus writing your statements in a more logical order.
So for example, this:
let testInts = [1;2;3;4;5;] let evenInts = List.filter (fun i -> i % 2 = 0) testIntsCan be re-written as this:
let testInts = [1;2;3;4;5;] let evenInts = testInts |> List.filter (fun i -> i % 2 = 0)This example is trivial of course, but where this really starts to shine is when you can effectively describe an entire program in one chain of function calls:
let oddPrimes = testInts |> filterOdds |> filterPrimesBasically what's happening here is that the value on the left of the pipe forward operator is being passed as the last parameter to the function on the right. In the first example, List.filter takes two parameters. The first is a function, and the second is a list. You'll find that all the functions in F# modules are structured so that the parameter most likely to be passed down a chain like this is defined as the last parameter.
At first I didn't think this was mind blowing at all. It just looked like a simple compiler trick. But then I learned this isn't in the compiler at all. In fact, |> is just a single line F# function. It's definition is nothing more than:
let (|>) x f = f x
let evenInts = List.filter (fun i -> i % 2 = 0) <| testIntsAnd it is defined as:
let (<|) f x = f xIf you've followed along this far, I hope you are boggling your mind as to what possible purpose this could serve! I know I was. The answer comes from the fact that operators have higher precedence in F#. So the pipe backwards operator allows you to avoid wrapping an expression in parenthesis. For example:
let output = "the result is: %d" (2 + 2)Those parenthesis are such a drag. So we can rewrite this without them as:
let output = "the result is: %d" <| 2 + 2