Stories
Slash Boxes
Comments

SoylentNews is people

posted by Fnord666 on Saturday June 20 2020, @03:04AM   Printer-friendly
from the depends-on-whether-you-code-using-emacs-or-vim? dept.

Are 80 Characters Per Line Still Reasonable In 2020?

[...] In case of the Linux kernel, that's of course [Linus Torvalds], who has recently shaken up the community with a mailing list response declaring an overly common, often even unwritten rule of code formatting as essentially obsolete: the 80-character line limitation. Considering the notoriety of his rants and crudeness, his response, which was initiated by a line break change in the submitted patch, seems downright diplomatic this time.

[Linus]' reasoning against a continuing enforcement of 80-char line limits is primarly the fact that screens are simply big enough today to comfortably fit longer lines, even with multiple terminals (or windows) next to each other. As he puts it, the only reason to stick to the limitation is using an actual VT100, which won't serve much use in kernel development anyway.

Allowing longer lines on the other hand would encourage the use of more verbose variable names and whitespace, which in turn would actually increase readability. Of course, all to a certain extent, and [Linus] obviously doesn't call for abolishing line breaks altogether. But he has a point; does it really make sense to stick to a decades old, nowadays rather arbitrary-seeming limitation in 2020?

The article then gives an overview of the history of how 80 columns became the de facto standard width. Though mentioned briefly in passing, it all really got started with the invention of the punched card dating back to 1804 when "Joseph Marie Jacquard demonstrated a mechanism to automate loom operation". The physical size of the punch card used in the 1890 United States Census was the same as US currency at that time. The cards were then known as "Hollerith cards" after the inventor Herman Hollerith. Later, IBM came to dominate the field.

As technology progressed, punch cards eventually gave way to computer terminals such at the IBM 3270 and "glass TTYs" like the DEC VT05 and Lear Siegler ADM-3A.

Computer languages were even designed around that common size. Both FORTRAN and COBOL had fixed line layouts with certain columns reserved for such things as sequence numbers, comment indicator, continuation marker, as well as the code itself.

Human factors play a role, too. A newspaper could, for example, have lines of text as long as the page is wide. It was found to be difficult to connect visually where the next line would start when one reached the end of a physical line. Hence multiple columns of text on a page. The same often holds for magazines, too.

Back to the question at hand.

I have personally used punch cards, FORTRAN, COBOL, and all of the computer terminals listed. I generally aim for 80-columns in the code I write, but I am flexible about it. Should I find that 90-100 columns better allows me to express and comprehend the code I've written, I'll err on the side of using more columns. A quick look through some code I've written revealed one case where I used 132 columns.

What about you? Hard and fast limit of 80 columns and not a single column more? 80-90? 100? Whatever it takes? Where and how do you draw the line?


Original Submission

 
This discussion has been archived. No new comments can be posted.
Display Options Threshold/Breakthrough Mark All as Read Mark All as Unread
The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
  • (Score: 5, Insightful) by fishybell on Saturday June 20 2020, @04:06AM (18 children)

    by fishybell (3156) on Saturday June 20 2020, @04:06AM (#1010261)

    Original diff that was rejected (which fails in the worst kinds of way):

    -ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos)
    +ssize_t __kernel_write(struct file *file, const void *buf, size_t count,
    +               loff_t *pos)

    Diff I would prefer:

    -ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos)
    +ssize_t __kernel_write(
    +                        struct file *file,
    +                        const void *buffer,
    +                        size_t count,
    +                        loff_t *position
    +                      )

    The push for saving a few characters here and there makes so much code so unreadable. Yes, too wide of lines makes code unreadable, but not as a bad as arbitrarily lopping off one parameter. Also, what's wrong with longer variable names? Are the extra three characters at the end of "buffer" too much? When is coding really slowed down by typing speed vs. everything else that goes into it?

    Starting Score:    1  point
    Moderation   +3  
       Insightful=3, Total=3
    Extra 'Insightful' Modifier   0  
    Karma-Bonus Modifier   +1  

    Total Score:   5  
  • (Score: 2) by JoeMerchant on Saturday June 20 2020, @04:15AM (12 children)

    by JoeMerchant (3937) on Saturday June 20 2020, @04:15AM (#1010266)

    Diff I would prefer:

    -ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos)
    +ssize_t __kernel_write( struct file *file ,
    + const void *buffer ,
    + size_t count ,
    + loff_t *position
    + )

    -----

    I can C clearly now, the brain has gone.

    --
    🌻🌻 [google.com]
    • (Score: 2) by JoeMerchant on Saturday June 20 2020, @04:17AM (11 children)

      by JoeMerchant (3937) on Saturday June 20 2020, @04:17AM (#1010267)

      Wow, should have previewed...

      Diff I would prefer:

      -ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos)
      +ssize_t __kernel_write( struct file *file    ,
      +                         const void *buffer  ,
      +                             size_t  count   ,
      +                             loff_t *position
      +                      )

      --
      🌻🌻 [google.com]
      • (Score: 0) by Anonymous Coward on Saturday June 20 2020, @05:00AM

        by Anonymous Coward on Saturday June 20 2020, @05:00AM (#1010277)

        That is an interesting one I'll have to think about. That alignment is interesting. A part of me prefers the style of always having the final comma and having the first argument on its own line as well. But other than that, I'll have to give it some thought. Maybe align all of the type declaration? Hmm. The gears are churning.

      • (Score: 2) by maxwell demon on Saturday June 20 2020, @05:18AM (3 children)

        by maxwell demon (1608) on Saturday June 20 2020, @05:18AM (#1010281) Journal

        I don't like the left-ragged types, nor the split-off commas or closing parenthesis.
        What's wrong with the following?

        -ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos)
        +ssize_t __kernel_write(struct file *file,
        +                       const void  *buffer,
        +                       size_t       count,
        +                       loff_t      *position)

        --
        The Tao of math: The numbers you can count are not the real numbers.
        • (Score: 1, Funny) by Anonymous Coward on Saturday June 20 2020, @06:40AM (1 child)

          by Anonymous Coward on Saturday June 20 2020, @06:40AM (#1010291)

          I get the impression of violinists contrasting techniques on the deck of the Titanic.

          • (Score: 2) by maxwell demon on Saturday June 20 2020, @11:03AM

            by maxwell demon (1608) on Saturday June 20 2020, @11:03AM (#1010319) Journal

            I don't see the set of languages with C-like function declarations to be sinking any time soon.

            Languages with mostly this style of declaration include

            • C (of course) and C++ (obviously).
            • Java and C#
            • D
            • Raku (formerly known as Perl 6) when using the optional static typing

            Languages with function declaration similar to Pascal-style (basically C style with order of type and name reversed) include

            • Swift
            • Rust
            • Go
            • Scala

            These lists are not claimed to be anywhere near complete. Note that I omitted languages that are mostly or completely obsolete.

            Indeed, I expect the majority of new languages, whenever they include mandatory or optional static typing, to roughly follow either a C style or a Pascal style function declaration (the third option would be a Fortran style declaration, but I think that one has fallen out of favour a long time ago).

            --
            The Tao of math: The numbers you can count are not the real numbers.
        • (Score: 2) by JoeMerchant on Saturday June 20 2020, @12:10PM

          by JoeMerchant (3937) on Saturday June 20 2020, @12:10PM (#1010335)

          Matter of preference - I prefer the type to be closer to the variable it applies to.

          The split-off commas are an acquired taste which can be more palatable in larger table like structures - particularly sparse ones where they help identify a pattern that's not 100% consistent.

          Spaces after the parenthesis: I like to alternate those, makes it easier to identify matching open and closes if they have matching space or no space. I generally start with a space ( makes it easier to read the enclosed text (but it's a small thing) ).
           

          --
          🌻🌻 [google.com]
      • (Score: 2) by bart9h on Saturday June 20 2020, @11:19AM (2 children)

        by bart9h (767) on Saturday June 20 2020, @11:19AM (#1010322)

        I like to think the * as part of the type, so I prefer

        -ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos)
        +ssize_t __kernel_write( struct file* file    ,
        +                         const void* buffer  ,
        +                             size_t  count   ,
        +                             loff_t* position
        +                      )

        • (Score: 2) by JoeMerchant on Saturday June 20 2020, @12:13PM

          by JoeMerchant (3937) on Saturday June 20 2020, @12:13PM (#1010338)

          Fair point, I'm just stuck in my ways with the * on the variable. Drove me nuts when &references started becoming popular, at least the editors in IDEs mark them as distinct from variables passed by value.

          --
          🌻🌻 [google.com]
        • (Score: 4, Informative) by acid andy on Saturday June 20 2020, @03:06PM

          by acid andy (1683) on Saturday June 20 2020, @03:06PM (#1010387) Homepage Journal

          Watch that doesn't catch you out (in C and C++).


          //You may think b's a pointer to an int. It's not. It's just an int.
          int* a = 0, b = 0;


          //b is a pointer to an int here.
          int *a = 0, *b = 0;

          --
          If a cat has kittens, does a rat have rittens, a bat bittens and a mat mittens?
      • (Score: 2) by Thexalon on Saturday June 20 2020, @09:17PM (1 child)

        by Thexalon (636) on Saturday June 20 2020, @09:17PM (#1010466)

        I have a different preference for the extra arg or two, which often runs afoul of the code style police.

        -ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos)

        +ssize_t __kernel_write(struct file *file, const void *buf, size_t count,
        +                                                               loff_t *pos)

        I guess you could call this "right-justify".

        The point of this is to reduce my eye movement when reading: I'm already on the right side of the line by the time I know that additional arguments are coming, so it's right there to finish the list.

        --
        The only thing that stops a bad guy with a compiler is a good guy with a compiler.
        • (Score: 2) by JoeMerchant on Saturday June 20 2020, @09:31PM

          by JoeMerchant (3937) on Saturday June 20 2020, @09:31PM (#1010471)

          I used to stick with the single line most of the time, but I've taken to the vertical list lately, particularly for stuff like:

            printf( "%s had a %s %s whose %s was %s as %s",
                    personName,
                    adjective,
                    subject,
                    possession,
                    possessionDescriptor,
                    possessionAnalogy );

          I also like to line up open and close parenthesis / brackets vertically, like:

            printf( "%s had a %s %s whose %s was %s as %s",
                    personName,
                    adjective,
                    subject,
                    possession,
                    possessionDescriptor,
                    possessionAnalogy
                  );

          but as they say, it's guidelines more than rules. I will say that this:

            function foo() {
                do;
                some;
                stuff;
                function nested() {
                    other;
                    stuff;
              }
            }

          drives me up the damn wall, particularly when it's non-trivial stuff in the function. When I see code like that in my projects I know it's something that I've copy pasted in and haven't really reviewed yet. After review it would look more like:

            function foo()
              { do;
                some;
                stuff;
                function nested()
                  { other;
                    stuff;
                  }
              }

          --
          🌻🌻 [google.com]
      • (Score: 0) by Anonymous Coward on Monday June 22 2020, @01:33AM

        by Anonymous Coward on Monday June 22 2020, @01:33AM (#1010867)

        If you like your commas aligned so much, put them in front.

        -ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos)
        +ssize_t __kernel_write(struct file *file
        + ,const void *buffer
        + ,size_t count
        + ,loff_t *position
        + )

        Easier to check for missing commas. Even if the line extends off the screen...

        Heck if you want even more stuff aligned:

        -ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos)
        +ssize_t __kernel_write
        + (struct file *file
        + ,const void *buffer
        + ,size_t count
        + ,loff_t *position
        + )

  • (Score: 1, Interesting) by Anonymous Coward on Saturday June 20 2020, @04:58AM (1 child)

    by Anonymous Coward on Saturday June 20 2020, @04:58AM (#1010275)

    I don't understand the value of placing each parameter on its own line. People generally understand what buf and pos are, just like i and j are understood as counters in loops. In other cases when the variable's purpose is less obvious, I'd be all for avoiding abbreviations, though I don't think it's necessary in that instance. Extending a single function call across several lines reduces the amount of code visible on the screen at any particular time, which actually makes code less readable. If I want to understand what a block of code does, it's easier if I can see more of the block of code at once. Needlessly long function calls make that more difficult. The original function call with everything on one line is just fine with me. But yes, use more descriptive variable names when it's less obvious what the variables do.

    I like the use of wide tabs for indenting code, something that Linus also mentions in his post. I prefer to just press tab once for each level of indentation. It's wide enough to make it readable. Plus it's quicker than having to press the space bar many times to achieve the same indentation, though some editors do this automatically. While I'm on the subject of indentation, the programmer should be able to decide how much indentation is needed for their particular use case. Indentation should not be used by compilers or interpreters to delineate the beginning and end of control structures. Python's use of indentation to define blocks of code is an absolute abomination.

    • (Score: 0) by Anonymous Coward on Sunday June 21 2020, @02:57AM

      by Anonymous Coward on Sunday June 21 2020, @02:57AM (#1010553)

      A lot of these conventions date back to when people exchanged diffs through mail and centralized systems like CVS. They make the code changes much cleaner while also making it easier to parse in your head. For example:

      int func(
              int x,
              int y,
              int z
      ) {
              /* do stuff */
      }

      The closing brace aligned with the if statement shows what your closing scope is. Each parameter on its own line makes it more obvious what types and variables you are dealing with while making the actual changes easier to spot in the diff. And try parsing something like that in your head when the declarations are more complicated "int const * const x, int * const y, int const * z" or includes structs or other complicated types. Once you get the variables in your head, you don't really have to refer back to them; and when you do because there are too many or you lost your source reference it is easier to spot the one you are looking for when it is spread out rather than in a bunch so you can quickly get back to what you were doing.

  • (Score: 2) by coolgopher on Saturday June 20 2020, @05:09AM

    by coolgopher (1157) on Saturday June 20 2020, @05:09AM (#1010279)

    Nothing at all wrong with the original in my view (even if I'm largely in the 80 camp). All arguments have sensible names (i.e. easy to understand, and not too long), and with only four of them it's easier to read on the one line with the added bonus of easy "grep"ability. Besides, "buf" and "pos" are as canonical as "i" in a for loop.

  • (Score: 2) by jb on Saturday June 20 2020, @08:53AM (1 child)

    by jb (338) on Saturday June 20 2020, @08:53AM (#1010306)

    -ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos)
    +ssize_t __kernel_write(struct file *file, const void *buf, size_t count,
    + loff_t *pos)

    Why not just put the return type on a line of its own, i.e.:

    -ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos)
    +ssize_t
    +__kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos)

    Not only does that fit on the screen more easily, but if applied consistently across your code base, it also gives you the benefit of being able to find any function definition quickly with a simple `find . -type '*.c' | xargs grep ^name_of_function`.

    • (Score: 0) by Anonymous Coward on Monday June 22 2020, @11:01PM

      by Anonymous Coward on Monday June 22 2020, @11:01PM (#1011290)

      Perhaps you should look into K&R, as opposed to ANSI, style.