Elixir: Improve code formatter output for tuples

Created on 24 Oct 2017  路  5Comments  路  Source: elixir-lang/elixir

Environment

  • Elixir 1.6.0-dev (894bcaa) (compiled with OTP 20)

Current behavior

The code formatter can produce less readable code (than manual formatting) when working on certain types of data, such as large tuple-trees (nested tuples and lists).

For example, the following manually formatted code:

@document Meeseeks.Parser.parse(
  {"html", [], [
     {"head", [], []},
     {"body", [], [
          {"div", [], [
              {"p", [], ["1"]},
              {"p", [], ["2"]},
              {"div", [], [
                  {"p", [], ["3"]},
                  {"p", [], ["4"]}]},
              {"p", [], ["5"]}]}]}]})

is formatted by the formatter to:

@document Meeseeks.Parser.parse({
            "html",
            [],
            [
              {"head", [], []},
              {
                "body",
                [],
                [
                  {
                    "div",
                    [],
                    [
                      {"p", [], ["1"]},
                      {"p", [], ["2"]},
                      {"div", [], [{"p", [], ["3"]}, {"p", [], ["4"]}]},
                      {"p", [], ["5"]}
                    ]
                  }
                ]
              }
            ]
          })
Elixir Chore Advanced Discussion Formatter

Most helpful comment

We can probably aim to have something like this:

@document Meeseeks.Parser.parse(
            {"html", [], [
              {"head", [], []},
              {"body", [], [
                {"div", [], [
                  {"p", [], ["1"]},
                  {"p", [], ["2"]},
                  {"div", [], [{"p", [], ["3"]}, {"p", [], ["4"]}]},
                  {"p", [], ["5"]}
                ]}
              ]}
            ]}
          )

All 5 comments

We can probably aim to have something like this:

@document Meeseeks.Parser.parse(
            {"html", [], [
              {"head", [], []},
              {"body", [], [
                {"div", [], [
                  {"p", [], ["1"]},
                  {"p", [], ["2"]},
                  {"div", [], [{"p", [], ["3"]}, {"p", [], ["4"]}]},
                  {"p", [], ["5"]}
                ]}
              ]}
            ]}
          )

The above means we will apply the same principle we have in function calls to tuples: if the last element is a data structure, we make it fit. We should also probably normalize {:ok, [foo: :bar]} to {:ok, foo: :bar}, as we do for function calls.

I prefer @mischov's example, but in @josevalim's example it's easier to keep track of matching delimiters. I'm a little torn on this, becuase @mischov's example reminds me of Lisp (which has the most aesthetically pleasing code layout I've seen), but despite my love for Lisp-like layout, Elixir is not Lisp, and my most nested code looks like this:

defrule tuple(
    seq([
      tag(:open,
        token(lit(?{), Tok.punctuation)
      ),
      tag(:middle,
        repeat(lookahead_not(lit(?})) |> root_element())
      ),
      tag(:close,
        token(lit(?}), Tok.punctuation)
      )
    ])
  ), pipe_result_into: process_delimiter_groups

which is similar to @josevalim's example. So, if I had to vote, I'd vote for Jos茅's....

EDIT: for the actual task of writing a DSL for HTML I prefer the first example! It's only because the formatter must work the same way in all cases.

Thanks @tmbb.

I should add that the only reason we are considered an alternative formatting here is because we already use said alternative formatting in the formatter. :) Otherwise it would be unlikely we would introduce another style.

This is now in master: f09657180fc28412b88e8877d30efbe0d9a84233!

Was this page helpful?
0 / 5 - 0 ratings