Flow user here, love it. Use it everyday. I simply re-export it via my custom prelude, then import my custom prelude in all modules.
I tried not using Flow for a while, but what I found was that, when I’m multiple levels deep into some codepath (you know when you lose track of space and time and get lost in the logic) and I need to decide what a function does, it’s much easier to read |> than $; trying to mentally parse $ takes me out of the context of the codepath and then I have to re-gain my bearings before I start writing code, and it’s worse when I have to reverse the order of the logic[1]. I think this is because of onomatopoeia: the |> function looks like it pipes some data through a function, whereas $ does not give me that impression at all. The standard >>= also looks like it pipes some data through a monad.
[1]: Consider this:
sequence $ func2 $ map func1 $ myData
versus this:
myData
|> map func1
|> func2
|> sequence
IMO the second is so much nicer to read and follow.
So far the comments I’ve shown have been personal attacks
Only 2 of the 6 comments up to the point this comment is made have anything personal in them. They seem to be “attacking” the concepts, not the person.
Hi! Author here. Now that I’ve had some time to mellow, I wouldn’t call those “personal attacks”. At the time I was excited about functional pipelines (probably thanks to Elixir). No Haskell libraries provided the (|>) pipeline operator. I created Flow to fill that gap. I shared it on Reddit because I wanted to know why pipelines weren’t popular in the Haskell community. It got over 100 comments, which is huge for r/haskell. In my opinion, most of the comments were negative. They derided the library by calling it “backwards” or a “hurdle” or a “crutch” or “exactly what functional programming is trying to avoid”. I took those comments personally when I shouldn’t have.
These days I just import Data.Function ((&)) and wince a little every time I write (&) instead of (|>). It’s definitely not as popular as ($) and (.), but it’s hard to call it non-standard when it’s in the base package.
I’ve always found the “backwards” notation of & a bit odd, but as you say in your post, different notations have different uses or people who prefer them. I know haskellforall has done some stuff with & around the “make Haskell look like OOP” experiments.
I mean, >>= is in this direction as the “default” so that’s not uncommon at all. I wonder if you could do some fun stuff with >>= and Identity
I usually prefer (&) because it encourages iterative development. Start with some value, transform it, and keep doing that until you have the result you want. That’s how I usually work in GHCi. The alternative is to start at the “outside” and keep working in until you’re at the bottom. I find that way of developing to be better when I already have the type signature and I’m filling in typed holes.
Fun fact: You can use do notation with pure computations in Haskell.
f :: Int -> Int
f x = do
let y = x + 2
let z = x * 2
y + z
I don’t understand what the big deal is, we read from left to right not right to left. It’s just a notational convenience I really don’t understand how people could get so conservative that they can’t even handle a different direction of function composition. If you wrote right to left, I could see that being a serious inconvenience though.
It’s confusing to me that the Haskell community would be resistant to the pipe operator since it’s IMO it’s been pretty successful in Elixir, Elm, F#, and OCaml. Maybe symptomatic of something unhealthy about the Haskell community in general.
The Haskell community is prone to err on the side of centralization to avoid fragmentation (unlike Lisps that are scattered into incompatible ecosystems, making writing anything practical much more of a chore than it should be) and has deep and ideological aversion to duct tape instead of proper fix. In this case: Flow functions are slightly more intuitive and IDE-friendly, but they do not address Haskell legacy usability problems in depth (a library is not a proper place for fixing the language), thus the community is very reluctant to use this.
I don’t see anything unhealthy about this, it is a conscious and rational choice (that has its downsides, yes).
Flow user here, love it. Use it everyday. I simply re-export it via my custom prelude, then import my custom prelude in all modules.
I tried not using Flow for a while, but what I found was that, when I’m multiple levels deep into some codepath (you know when you lose track of space and time and get lost in the logic) and I need to decide what a function does, it’s much easier to read
|>than$; trying to mentally parse$takes me out of the context of the codepath and then I have to re-gain my bearings before I start writing code, and it’s worse when I have to reverse the order of the logic[1]. I think this is because of onomatopoeia: the|>function looks like it pipes some data through a function, whereas$does not give me that impression at all. The standard>>=also looks like it pipes some data through a monad.[1]: Consider this:
versus this:
IMO the second is so much nicer to read and follow.
Only 2 of the 6 comments up to the point this comment is made have anything personal in them. They seem to be “attacking” the concepts, not the person.
Hi! Author here. Now that I’ve had some time to mellow, I wouldn’t call those “personal attacks”. At the time I was excited about functional pipelines (probably thanks to Elixir). No Haskell libraries provided the
(|>)pipeline operator. I created Flow to fill that gap. I shared it on Reddit because I wanted to know why pipelines weren’t popular in the Haskell community. It got over 100 comments, which is huge for r/haskell. In my opinion, most of the comments were negative. They derided the library by calling it “backwards” or a “hurdle” or a “crutch” or “exactly what functional programming is trying to avoid”. I took those comments personally when I shouldn’t have.These days I just
import Data.Function ((&))and wince a little every time I write(&)instead of(|>). It’s definitely not as popular as($)and(.), but it’s hard to call it non-standard when it’s in thebasepackage.I’ve always found the “backwards” notation of
&a bit odd, but as you say in your post, different notations have different uses or people who prefer them. I know haskellforall has done some stuff with&around the “make Haskell look like OOP” experiments.I mean,
>>=is in this direction as the “default” so that’s not uncommon at all. I wonder if you could do some fun stuff with>>=andIdentityI usually prefer
(&)because it encourages iterative development. Start with some value, transform it, and keep doing that until you have the result you want. That’s how I usually work in GHCi. The alternative is to start at the “outside” and keep working in until you’re at the bottom. I find that way of developing to be better when I already have the type signature and I’m filling in typed holes.Fun fact: You can use
donotation with pure computations in Haskell.Yes, you can have non-recursive let!
I don’t understand what the big deal is, we read from left to right not right to left. It’s just a notational convenience I really don’t understand how people could get so conservative that they can’t even handle a different direction of function composition. If you wrote right to left, I could see that being a serious inconvenience though.
It’s confusing to me that the Haskell community would be resistant to the pipe operator since it’s IMO it’s been pretty successful in Elixir, Elm, F#, and OCaml. Maybe symptomatic of something unhealthy about the Haskell community in general.
Yeah it’s great and haskell often forgets people like to program to do things.
Avoid success at all cost taken a lil’ too far.
The Haskell community is prone to err on the side of centralization to avoid fragmentation (unlike Lisps that are scattered into incompatible ecosystems, making writing anything practical much more of a chore than it should be) and has deep and ideological aversion to duct tape instead of proper fix. In this case: Flow functions are slightly more intuitive and IDE-friendly, but they do not address Haskell legacy usability problems in depth (a library is not a proper place for fixing the language), thus the community is very reluctant to use this.
I don’t see anything unhealthy about this, it is a conscious and rational choice (that has its downsides, yes).