As for strings, meh. But consistency is nice. Line length exceeding an arbitrary standard, fine. Rules can be broken if there's a good reason.
As for strings, meh. But consistency is nice. Line length exceeding an arbitrary standard, fine. Rules can be broken if there's a good reason.
As a smug lisp weenie that has been working in python for many years, I completely disagree with this.
> you just waste time re-justify everything if you refactor.
A single `indent-region` in emacs and you are rejustified, no trouble.
> It's just more effort in the long run, and for what?
It's more effort as opposed to what, exactly?
> It isn't prettier, more readable, or more convenient.
It is, to me, prettier, but I think, objectively, it is more readable than alternatives, especially if there is any kind of nesting involved.
I concede that if there is nesting involved, you might be bumping into other python style issues, and generally might want to add some intermediate variables, etc; however, I do believe that in at least some cases this is entirely inconvenient, and so the lisp way of aligning parameters with their delimiter is the way to go in those cases. Anything else would be quite a bit less readable.
Yeah, I'll just change my text editor because someone in the team wants to use this rule.
So convenient.
> A single `indent-region` in emacs and you are rejustified, no trouble.
Because when you refactor the function/class name, it's never just one region. So now you have to go back and indent all occurrences, maybe even over multiple files. Brilliant!
... the region is whatever you say it is:
(mark-whole-buffer)
(indent-region)
Or, most likely, something like: C-x h TABI don't think that's particularly onerous.
It's only a few lines of elisp to visit all the files in a tree and automatically format them. That said, it would probably be more sensible to modify whatever refactoring tool to be indentation aware, if it isn't already. Again, that's easy to do with elisp.
But I'm not clear what's being suggested in the article. Personally, I'd turn:
foo = long_function_name(var_one, var_two,
var_three, var_four)
into: foo = long_function_name(
var_one, var_two, var_three, var_four
)
or: foo = long_function_name(
var_one,
var_two,
var_three,
var_four,
)
depending on the actual length. (Or all on one line if short enough of course.)"Aligned with opening delimiter" basically just means "put all the code as close to our column limit as possible", which is nuts.
def very_long_function_name(arg_one, arg_two, arg_three, arg_four):
... def very_long_function_name(
arg_one,
arg_two,
arg_three,
arg_four
):
It's consistent and doesn't require spaces so it lets you use tabs to let the reader choose its indentation size. def very_long_function_name(
arg_one,
arg_two,
arg_three,
arg_four
):
pass
For data structures, I definitely prefer the bracket to be on it's own line, but for function definitions I don't, so I'm also a fan of: def very_long_function_name(
arg_one,
arg_two,
arg_three,
arg_four):
pass
def very_long_function_name(
arg_one, arg_two, arg_three, arg_four):
pass def very_long_function_name(
arg_one, arg_two, arg_three, arg_four):
pass
Please don't. It looks awful.`):` always either on the first (and only) line or the last line, which ensures it either over-runs the function body indention level, or falls short:
def a():
pass
def b(
):
pass def very_long_function_name(
arg_one,
arg_two,
arg_three,
arg_four
):
...
The nice thing here is that the close parenthesis separates the parameters from the function body, without having to do anything like double-indenting.What's interesting to me is to try to understand why people are attracted to the column-aligned style even when it has so many problems. I think it comes directly from being unwilling to put spaces inside the parentheses when it's a one-liner:
long_function_name(var_one, var_two, var_three, var_four)
If you find that line getting too long and want to break it into multiple lines, it's natural that the first thing you do is to turn spaces into newlines: long_function_name(var_one,
var_two,
var_three,
var_four)
Well that's ugly, so what can we do with it? A few people indent the arguments after the first one: long_function_name(var_one,
var_two,
var_three,
var_four)
That doesn't make much sense; why is the first argument not lined up with the rest? So the next natural thing to try is the column aligned style: long_function_name(var_one,
var_two,
var_three,
var_four)
And now you have the problems that brings; fiddly maintenance and excessive line lengths.But what if you cultivate a style of putting spaces inside the parens, like this:
long_function_name( var_one, var_two, var_three, var_four )
Now when you have to break it into multiple lines, the natural place to start is again to turn the spaces into newlines: long_function_name(
var_one,
var_two,
var_three,
var_four
)
and from here it's simple to add some indentation: long_function_name(
var_one,
var_two,
var_three,
var_four
)
What I haven't figured out is why so many programmers are opposed to putting spaces inside the parentheses. Not only does this lead to better practices when you switch back and forth between single line and multiline styles, but it's more logical too. In this example, the open paren "belongs" to the function call, not to the first argument. Why should the arguments get spaces between then, but the first argument is a special case, directly attached to the function name?In fact, PEP8, if you take it as gospel, forbids spaces inside the parentheses. But as is common with these things, it gives no reason or rationale for this. It's simply listed as a "pet peeve".
I've seen a few style guides where the authors realized it would be nice to have some whitespace between the function name and first argument, but just couldn't bring themselves to try putting the space inside the parentheses, so they put it outside:
long_function_name (var_one, var_two, var_three, var_four)
A lot of Unity C# code is written like this, because it's MonoDevelop's default style. It's not terrible when you see a simple example, but it gets pretty bad when there are nested functions: DoSomething (Foo (x), Bar (y))
The whitespace here has very little to do with the actual structure of the code. Contrast this with: DoSomething( Foo(x), Bar(y) )
Now the things that belong most closely together are visually connected, and spaces separate the things that are less connected. I didn't put spaces inside the parens for the inner functions, only the outer one, to help emphasize what is connected to what.