Dec 232013
 
 December 23, 2013  Posted by at 7:41 pm C# & F#  Add comments

When I first learned about the backwards pipe I was excited and immediately thought that it was rather cool. If you don’t know what a pipe is, it simply allows you to chain methods making the return value of one the input parameter of the next one. In F# it’s commonly seen as |> for forward piping, and <| for backwards piping. After getting over the ‘this is so cool’-feeling I realized I had no idea what to use it for. So in the air between Oslo and Stavanger (Norway) I decided to think about it a little bit and share what I know so far. F-sharpies might want to add to this post if you know some more, I’m a beginner in terms of F#.

reversePipeFSharp

The backwards pipe operator, <|, applies a function on the left of the operator to the value on the right of the operator.

Example:

let sum nrX nrY = nrX + nrY

// No parenthesis…yay! (?)

printfn “If we add we get…. %d” <| 2 + 3

// Oh noes.. parenthesis *sad face*

printfn “If we add we get…. %d” (2 + 3)

// Don’t get me started on double and triple reverse pipe operators

sum <|| (2,3)

In short, the only application I can find for the backwards pipe in F# is avoiding trailing parenthesis (but not always). Can this be true? This is it? I’m sure there must be more. Feel free to share if you know =)

  13 Responses to “What purpose does the backward pipe serve in F#? (Q262)”

  1. I find it useful on those occasions when you have a chain of pipes, but for one of them you want to pass the data in as the FIRST param, rather than the last.

    Here’s an example:

    // setup some functions
    let replace (oldS:string) newS (a:string) =
    a.Replace(oldS,newS)
    let add a b =
    sprintf “%s %s” a b
    let toUpper (a:string) =
    a.ToUpper()

    // pipe “hello” through the functions
    “hello”
    |> replace “h” “j”
    |> add “world” // “world is first param
    |> toUpper

    //result “WORLD JELLO” // not what we want

    // pipe “hello” through the functions
    “hello”
    |> replace “h” “j”
    |> add toUpper

    //result “JELLO WORLD” // correct!

    • (again, with better formatting!)

      // setup some functions
      let replace (oldS:string) newS (a:string) = a.Replace(oldS,newS)
      let add a b = sprintf “%s %s” a b
      let toUpper (a:string) = a.ToUpper()

      // pipe “hello” through the functions
      “hello”
      |> replace “h” “j”
      |> add “world” // “world is first param
      |> toUpper

      //result “WORLD JELLO” // not what we want

      // pipe “hello” through the functions
      “hello”
      |> replace “h” “j”
      |> add toUpper

      //result “JELLO WORLD” // correct!

  2. Yes backwards pipe is mostly used to avoid the closing paranthese. It’s a bit like $ in haskell (explained here: http://learnyouahaskell.com/higher-order-functions#function-application)

    Basically the reason is that one wants to lower the precendence of the function application operator.

    When you type:
    printfn “%A” 1 + 2

    The F# compiler places the paranthesis like this due to precendence and left associativity of function application operator (http://msdn.microsoft.com/en-us/library/dd233228.aspx):
    (((printfn “%A”) 1) + 2)

    This won’t compile which is why you have to either use parantheses or (printfn “%A”) (1 + 2)
    printfn “%A” (printfn “%A”) <| (1 + 2)

    The benefit of <| is mostly seen when the right-side expression spans several lines.

    <| in F# isn't quite as good as $ in haskell though because . $ in haskell has the lowest precedence and is right associative which for this particular reason is what you want. Example of when <| fails us:
    printfn "%A" List.filter (fun x -> x%2 = 0)

    (the problem is that have the same precendence and associativity which makes the F# compiler place the parantheses “wrongly”)

    PS. The definition of backward pipe: let inline ( ) x f = f x
    PS. Had to switch to Chrome to post here. Just FYI.

    • I notice the WP in it’s wisdom are sometimes removing <| which breaks some of the code-samples.

    • Another place when <| shines is that F# warns when you call a function that returns a value you don't handle:
      x.DoStuff ()

      F# then asks you to either act on the value or ignore it:
      ignore (x.DoStuff ())

      I just prefer
      ignore <| x.DoStuff ()

      PS. This is something I wished for along time for C# so IMHO this warning is a good one

    • WRT to <|| and <||| I think the purpose of those is slightly different.

      If you have a F# function taking two arguments and the values you have are in a tuple <|| can help.

      You can do this:
      let x,y = myTuple
      let s = sum x y

      or this:
      let s = sum (fst myTuple) (sndmyTuple)

      But with <|| you do this:
      let s = sum <|| myTuple

  3. The primary purpose of the operators |> and for the “backward” variant, though I will use your naming style here, with |> being forward and g |> h instead. This is nice since it also behaves better with newlines. You can line up the |> operators underneath each other and get a clearer view of what happens. Especially if g, say, is a composition of several other small functions.

    In functional programming, it is common to have many small functions which are then composed to form the program. We need some tools to glue functions into compositions and this is where the >>, |> and is glue for puzzle pieces that allows you to put them together in different ways.

    The story of <| is almost the same. In code which is composition-heavy, you often have to read the code from right-to-left rather than left to right. In h(g(f(x))) the application of the inner function, f, happens first. Then g and finally h. So functional programmers often compose code in a right-to-left style. The backwards pipe is a bit more readable in this style: h <| g <| f x. And it follows the natural direction of the function call application.

    <|| and <||| are just different variants for working with 2- and 3-tuples respectively. The pieces must fit together so things are type-correct. Hence their existence.

    So the reason is mostly for giving the programmer different options for expressing their code to a reader. It is nice to be able to throw in either to delimit other groups of code and make it easier to read.

  4. Oops, my less-thans got eaten by the blog software and made the description meaningless. Here is the full text:

    https://gist.github.com/jlouis/8111923/raw/a453f1bd9efb054459142621e707949afeecbce3/gistfile1.txt

  5. The operator <| in F# obviously corresponds to the operator $ in Haskell. That's defined by f $ x = f x, which by itself seems quite meaningless. But the associativity and precedence is set so that f $ g $ h $ x = f (g (h x)) and $ can thus be used to reduce the numbers of parenthesis.

  6. Yes, it looks like those threading macros @Bodil were talking about at Oredev. In the right pipe you put stuff as first arg, and with left pipe as last arg.

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)

What is 12 + 15 ?
Please leave these two fields as-is:
IMPORTANT! To be able to proceed, you need to solve the following simple math (so we know that you are a human) :-)