christopheradams / elixir_style_guide

A community driven style guide for Elixir
4.37k stars 300 forks source link

Multiline pipeline syntax #103

Closed syamilmj closed 5 years ago

syamilmj commented 8 years ago

Consider the codes below:

File.stream!("path/to/some/file", read_ahead: 100_000) # NEW!
|> Flow.from_enumerable()
|> Flow.flat_map(fn line ->
    for word <- String.split(empty_space), do: {word, 1}
   end)
|> Flow.partition_with(storage: :ets) # NEW!
|> Flow.reduce_by_key(& &1 + &2)
|> Enum.to_list()

Notice the pattern in this bit:

Flow.flat_map(fn line ->
  for word <- String.split(empty_space), do: {word, 1}
end)

for is only indented by two spaces, and end) is indented on the line as Flow

I have seen many different ways on how they were written, but this seems to be cleanest way.

Ref: http://elixir-lang.org/blog/2016/07/14/announcing-genstage/

christopheradams commented 8 years ago

In your pipes example and the one you link to for is only further indented by one space instead of two. Does that seem odd to anyone else?

asaaki commented 8 years ago

The pipe operator is not the nicest player when it comes to indentation based on factor 2, since it leads to 3 spaces in front of the statements.

123↓
|> Foobar
   not working, if "aligned" to above statement
   (3 spaces vs. 2 or 4 spaces)
|> sorry
123↓
|> Foobar
    not working, because we are off by 1 to above
    and are actually introducing 4 space intendation
|> sorry

How do I avoid such mess? In multiline pipes with multiline functions I always extract the functions, because they already distract the visual flow for the pipeline.

So personally I don't even care so much, if there was a guideline for multiline pipelines with necessary indentation, because I have the feeling that such pattern is already a bad one (like a code smell). But again, this is just my opinion.

christopheradams commented 5 years ago

Multiline pipeline syntax should now look like:

    File.stream!("path/to/some/file", read_ahead: 100_000)
    |> test()
    |> test(fn line ->
      for word <- String.split(" "), do: {word, 1}
    end)