1. 34
  1.  

  2. 11

    I’m amused by the reactions to this. Code formatting is the least interesting problem in programming, and one of the most easily automated. Props to Łukasz for this; I may not agree with every choice, but I agree that the choices should be made once and once only, and then just … used.

    1. 3

      Totally agree with you on principal!

      But it’s such a prolific topic for fun, pointless banter! :-) So why not? :-)

    2. 10

      From the readme:

      You probably noticed the peculiar default line length. Black defaults to 88 characters per line, which happens to be 10% over 80. This number was found to produce significantly shorter files than sticking with 80 (the most popular), or even 79 (used by the standard library). In general, 90-ish seems like the wise choice.

      This is a table stakes deal breaker for me. I know, I know, I’m likely old fashioned. I prefer old school. :-)

      1. 6

        It is a default though, you can pass --line-length to it.

        1. [Comment removed by author]

          1. 4

            Honestly though, is your terminal window really 80 columns wide? And should outdated defaults matter?

            1. 3

              Yes, my terminal window is really 80 columns wide.

              I also have a source file where a single line of code is 250 characters (and no, it really can’t be broken up due to semantic constraints).

              So, what should be the minimum width of a terminal window?

              1. 1

                I actually prefer to code with a 80-wide terminal most of the time, because it tends to remind me to simplify my code more than I would otherwise :o

              2. 1

                I think 79 is better than 80, because 79 allows for a single-column ruler on the side of the window and stuff

                1. 1

                  This is about the size of your code “viewport”, not of your terminal.

                  3 columns are already used by my line length indicator in vim, but that number is really arbitrary too.

                2. 1

                  departing from established standards because you feel like it is a pretty bad sign in general. as are --long-gnu-style-options, but that’s a different issue.

                3. 2

                  I just counted the length of lines over 266 Lua files [1], calculating the 95th percentile [2] of line length. Only 4% had a 95 percentile of 89 or higher; 11% had a 95th percentile of 80 or higher. And just because, 4% had 95th percentiles of 80 and 81. For maximum line lengths:

                  • 42% with longest line of 79 characters or less
                  • 46% with longest line of 80 characters or less
                  • 56% with longest line of 88 characters or less

                  Longest line found: 204 characters

                  [1] I don’t use Python, so I’m using what I have. And what I have are multiple Lua modules I’ve downloaded.

                  [2] That is, out of all the lines of code, 95% of line lengths are less than this length.

                  1. 1

                    https://en.wikipedia.org/wiki/88_(number)

                    I can’t help it but read it as a fascist code, or at least I start thinking about whether it could be on every occasion I see this number (not totally unfounded, because where I live it is used this way every now and then). I don’t think they meant to use it this way, so I think it’s fine (more than that, good, because it devalues the code by not treating the numebr as taboo).

                    1. 1

                      Personally I don’t like line break at 80 or 90 with python, as the 4-spaces indent quickly uses up a lot of horizontal space. For example, if you write unittest-style unit tests, before you write any assignment or call, you have already lost 8 spaces.

                      class TestMyFunctionality(unittest.TestCase):
                          def setUp(self):
                              # ....
                          def test_foo(self):
                              x = SomeModule.SomeClass(self.initial_x, get_dummy_data(), self.database_handle)
                      

                      Of course you could start introducing line breaks, but that quickly leads to debates on “hanging indent”, lisp-style-indent, etc. or you end up with a lot of vanity variables for local variables.

                      With lisp-style indent I mean the following snippet, that (if it was the way the autoformatter would do it would convince me to accept a 80 character line length limit)

                      class TestMyFunctionality(unittest.TestCase):
                          def setUp(self):
                              # ....
                          def test_foo(self):
                              x = SomeModule.SomeClass(self.initial_x,
                                                       get_dummy_data(),
                                                       self.database_handle)
                      

                      Whereas I find the “hanging indent” style makes understanding the structure of the syntax tree so much more difficult.

                      class TestMyFunctionality(unittest.TestCase):
                          def setUp(self):
                              # ....
                          def test_foo(self):
                              x = SomeModule.SomeClass(
                                      self.initial_x,
                                      get_dummy_data(),
                                      self.database_handle)
                      
                    2. 6

                      I’ve installed the vim plugin and so far I’m liking it. I’ve been rather spoiled by vim-go so it’s nice to see similar things for other languages.

                      The Black plugin for vim doesn’t include format-on-write but someone opened a pull request to demonstrate how to configure vim to do it.

                      I’ve added this to my .vimrc:

                      if has("autocmd")
                          augroup filetype_python
                              au!
                              au BufNewFile,BufRead *.py setlocal sw=4 sts=4 et
                              au BufWritePost *.py execute ':Black'
                              au FileType python setlocal sw=4 sts=4 et
                          augroup END
                      endif
                      
                      1. 6

                        No, no, no… Defaulting to double-quotes over apostrophes sends it to hell right away. I’m not fond of squeezing my left pinky over Shift the entire time I’m typing. Also, apostrophes are obviously more classy. Double-quotes smells too much of C and other C-inspired syntaxes.

                        On a slightly more serious note, if a line fits into the length limit doesn’t mean it should necessarily be reformatted this way. I prefer this:

                        return {
                            'AND': eval_and,
                            'OR': eval_or,
                        }[op](some, more, args, here)
                        

                        to not be turned into a one-liner. But black does.

                        1. 8

                          But that’s the point of Black—to remove all thought about formatting so no one can bikeshed coding styles. There are no aesthetic concerns taken into account period. If it’s ugly, it’s ugly. Get over your artistic tendencies and program—that’s what you are paid for.

                          Would I use this? No (that is, if I programmed in Python—I don’t). I’ve built up a coding style that works for me over the past 30 years, and yes, I am concerned with aesthetic concerns of code. Then again, I’ve been fortunate to work at places were I an use my personal coding style.

                          1. 1

                            Code style affects readability though, it’s not just about making it look pretty (I like pretty code too though). So the choices Black makes in that regard are important. Personally I don’t think automatic formatting tools should be too concerned with line length (except maybe in some very specific contexts) and they should just work with the lines they’re fed. The rules this tool uses for splitting lines seem fairly arbitrary and it’s one of the few areas where I think a human is better off making the call.

                            I’m not a Go programmer, but I think gofmt handles this better?

                        2. 1

                          This looks like a nice upgrade from autopep8