That is (sort of) the question.
I'm trying to learn F# more lately and my resources seem to prefer piping in places where it's not clear a benefit exists. For example, given a function in curried form:
f: a -> b -> c -> R
I can call it by supplying all the arguments inline or pipe c
in like so:
let r = f a b c
let r = c |> f a b
But is there a cost or benefit or is it purely a stylistic preference?
There should be no cost.
UPDATE
There may be some extra cost. Sometimes an extra call is inserted, but some other times the compiler can optimize it avoiding the extra call.
I tested the following code:
let concat (a:string) (b:string) = System.String.Concat(a, b)
let f1 g a c = g a c
let f2 g a c = c |> g a
f1 concat "b" "c" \\ 00:00:33.8895616
f2 concat "b" "c" \\ 00:00:34.6051700
concat "b" "c" \\ 00:00:35.0669532
"c" |> concat "b" \\ 00:00:35.1948296
f1 (+) "b" "c" \\ 00:00:35.4796687
f2 (+) "b" "c" \\ 00:00:49.3227193
(+) "b" "c" \\ 00:00:35.0689207
"c" |> (+) "b" \\ 00:00:35.8214733
For each case I performed a billion calls (1_000_000_000
) and those were the times. As you can see only calling f2 (+) "b" "c"
was slower than the rest which may have something to do with (+) being an operator that uses SRTP.
Thanks to @PhillipCarter for clarifying.
The use of pipe helps with type inference:
let words = "many words".Split ' '
let wordsU1 = words |> Array.map (fun w -> w.ToUpper()) // ok
wordsU1 |> Seq.iter (printfn "words are %A")
let wordsU2 = Array.map (fun w -> w.ToUpper()) words // type annotation needed: (w:string)
Seq.iter (printfn "words are %A") wordsU2
The two calls to Array.map
are equivalent but the second one complains that it does not know the type of w
. That is because F# type inference mechanism works from left to right and in the second case words
is after the lambda function.
It is also better stylistically. The code above can be better expressed like this:
"many words".Split ' '
|> Array.map (fun w -> w.ToUpper())
|> Seq.iter (printfn "words are %A")
So the pipe can be used to chain several expressions without having to use parenthesis or binding it to names.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With