Hacker News new | ask | show | jobs
by aeturnum 1988 days ago
I think OP's point about building huge systems with pipes is well taken. They can become confusing when the break and over-use can be a code smell.

Their power, as you point it, is in the ability to jump into any statement and add another action with minimal syntax. It's extremely useful while iterating on development because you can quickly check that something works (or check on what is happening).

2 comments

I think it also encourages a declarative style of programming, so that's a win if you ask me, especially for large systems, though I can't measure this.
If you’re chaining more than three or four things together I think you’re definitely doing something wrong but I’m not sure I’ve ever seen someone do that in Elixir.
I disagree. I think a common antipattern is piping only one thing.

This is good and readable:

    nuclear_missile
    |> open_hatch()
    |> open_fuel_lines()
    |> fire_thrusters(:all)
    |> configure_gps(%Coordinates{...})
This is unnecessary:

    word_count = 
      words
      |> Enum.count()
This is better:

    word_count = Enum.count(words)
Pipes read like a list of bullet points. We can easily deal with up to a dozen bullet points, but a single bullet point is bad grammar style.
the entire ecto api is built upon chaining statements together. I have a few queries that are 8-10 statements long.
Good point, I don’t use Ecto so I wasn’t aware of this.
Not an antipattern for nimble_parsec: https://github.com/ityonemo/zigler/blob/fe845a9fbbfef92da8ab...

Plus think of how much easier that pipe makes it for you to understand what is going on.

That’s a very beautiful usage of it. I hadn’t thought of it as a way to construct DSLs, but it makes a lot of sense here.
Looks like Haskell-like do notation would be helpful.
do you feel like the code presented is broken? I don't. Could it be better? Maybe... But how much? Is it worth a whole new pattern to learn?
My longest pipe chain in Elixir so far (with ~1 year of usage) is this[1], where I build a GraphQL context from an HTTP session. I personally think it's clean enough, but your comment made me wonder if it can be better.

[1] https://github.com/RodrigoLeiteF/craftup/blob/main/backend/l...