[Proposal] Clearer visual distinction between function arguments

53 views
Skip to first unread message

ivan.iv...@gmail.com

unread,
Jan 6, 2021, 7:25:54 AM1/6/21
to elixir-lang-core
Hello,

This is a wide topic  and I am going to illustrate it with one example from ExUnit.

Sometimes when a test fails, especially when `%Plug.Conn{}` is one of the arguments, in the stacktrace the reported function call is shown. The issue is that when there is a big map/struct as an argument and a few other arguments, it is very hard to see where one function argument ends and another starts.

One approach to improve the experience in this case is to paint the arguments in different colors.
Here is an artificial example that shows the problem.
Take a look at the  %SomeModule.three_arg_function/3 function that takes 3 arguments - %Plug.Conn{}, map and %Plug.Conn{}.

Without any visual distinction in the terminal you would see something like this: https://ibb.co/NnqMc1T

But if we throw some colors in, the arguments are clearly distinguished:
https://ibb.co/NnXYfcn

This ability to better visually distinguish the arguments can be applied in a wide variety of situations and not only in the ExUnit stacktrace. The problem can be solved in different ways that can be applied either separately or combined. One such another "trick" I use to better understand what happens is to copy the function header in a file and replace `\n` with actual new lines.

José Valim

unread,
Jan 6, 2021, 8:10:06 AM1/6/21
to elixir-l...@googlegroups.com
I think this is a great idea. I think we can break this problem in two:

1. Improve the readability of arguments in stacktraces (without color). We should probably break them into newlines by default. A PR for this is welcome.

2. Once we do that, we discuss and reassess the need for coloring.

WDYT?

--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/d984f624-9aa9-43c1-b553-f6a9883259dcn%40googlegroups.com.

ivan.iv...@gmail.com

unread,
Jan 6, 2021, 8:47:25 AM1/6/21
to elixir-lang-core
Should the breaking into new lines apply to all cases? The length of the string representation of the arguments and the arguments count might be important when deciding. Having a function that takes 6 integers (if this is good design is irrelevant here) is better written in one line than multiple:
`foo(1,2,3,4,5,6) `
vs
```
foo(
  1,
  2,
  3,
  4,
  5,
  6
)
```

The same applies for short structs/map. The rework should not lead in readability degradation for such cases.

Another question is should this new lines formatting be independent of the formatter or should it follow the formatter rules? Take for example the following function call:
```
some_function(%SomeStruct{name: "foo_foo_foo_foo_foo_foo_foo", id: 1}, %SomeStruct{name: "bar_bar_bar_bar_bar_bar", id: 2})
```

After running the formatter with the default line width, this results in:
```
some_function(%SomeStruct{name: "foo_foo_foo_foo_foo_foo_foo", id: 1}, %SomeStruct{
  name: "bar_bar_bar_bar_bar_bar",
  id: 2
})
```
while, if we truly put every argument on a new line, the format would be (the formatter would not transform this into the one above though):
```
some_function(
  %SomeStruct{name: "foo_foo_foo_foo_foo_foo_foo", id: 1},
  %SomeStruct{name: "bar_bar_bar_bar_bar_bar", id: 2}
)
```

This is actually one of the things that bugs me in the formatter and I would personally always prefer the second format everywhere, including the currently discussed topic.

José Valim

unread,
Jan 6, 2021, 9:16:56 AM1/6/21
to elixir-l...@googlegroups.com
> This is actually one of the things that bugs me in the formatter and I would personally always prefer the second format everywhere, including the currently discussed topic.

The formatter is always a hint. In the cases mentioned above, I would manually break them so each struct is on its own line. Which is the format we should go with.

For the minimal cases you presented, we should not break it into its own line. The current Inspect.Algebra should already handle said cases.

Reply all
Reply to author
Forward
0 new messages