Hacker News new | ask | show | jobs
by flatline3 5050 days ago
> Is that senior enough for you?

No. Have you read 70s and 80s C code? Tried tracing through the original UNIX kernel sources? Tried working with them?

To understand all the invariants of one small aspect of the system quite often requires tracing through the whole system until you get to a well-documented input/output module point (via comments, man pages, or otherwise).

Also, the quote (aside from it being out of context) says to not comment bad code.

> No, they are actually advocating to put more effort in thinking about stuff: how you name your functions/methods/whatever, how do you name your arguments/parameters, how do you write the code itself.

You can't define all the invariants -- or summarize for readability -- in pure code.

1 comments

> No. Have you read 70s and 80s C code? Tried tracing through the original UNIX kernel sources? Tried working with them?

Yes. It's some of the easiest to understand code I've read. For example, http://unixarchive.cn-k.de/PDP-11/Trees/V6/usr/sys/ken/slp.c

They're actually quite decently commented. The functions describe what they do clearly, and the bodies show how they do it tersely, with comments around the sticky bits.

Have you read through the original Unix kernel sources? Claiming that they're uncommented and difficult to work with is surprising. (On the other hand, the directory structure could be better.)

Without tracing the backing kernel structures and the code that relies on them, please describe why sleep(chan, pri) works, and as a maintainer, what I need to watch out for when modifying that code.

What does swtch() do? What does issig() do? Does that mean it's checking for a signal during sleep? What signals could be generated? Under what circumstances do I need to check for those signals? Are there any race conditions? Does ordering matter? What happens if I move the call to issig?

Beyond the invariants, this code is NOT READABLE. I can't just glance at the comments for an atomic unit of 4-5 LoC and see what it does -- I have to examine the code in depth, running the logic in my head, and explore the workings that way.

Reading code without comments is like tracing out a circuit without a schematic or documentation. First you have to manually establish the what, and only then can you even start to spend your time determining the why.

I work on modern BSD code. It's better than this old stuff, and I still have to dig to figure out how/why things are supposed to work. It's a headache compared to properly commented and documented code, where I can just skim standalone units and know what they do without having to trace everything myself.

Of course you need context to understand code. You can't get away from that without essentially translating the rest of the code into prose and attaching it to each line. At which point there are enough comments that you need context to figure out which parts of them you care about, reading them becomes a chore, and they essentially become noise. I've seen codebases with insane levels of commenting. I found myself ignoring the comments and tracing through the code.

If the model is simple and the code is clear, learning the context becomes easy, and it fits into your head. Following code becomes easy.

> Of course you need context to understand code.

Comments decrease the amount of code you must personally read and understand, and define invariants that can't be expressed purely through the code.

> At which point there are enough comments that you need context to figure out which parts of them you care about, reading them becomes a chore, and they essentially become noise.

I've never seen this outside of contrived examples from lazy developers that think they're too smart to need to comment their code.

> If the model is simple and the code is clear, learning the context becomes easy, and it fits into your head.

In other words, you must trace the entire system to understand it and then fit it into your head. This is not advantageous to maintainers.

> you must trace the entire system

No, just the part you care about. You do need a high level mental model of the system. I've never seen a system where this is not the case, regardless of the number of comments. Even literate programming -- or at least, the examples of it that I've seen -- suffered from this. (Amusingly, I found literate programming examples were often easier to understand by mostly ignoring the prose and looking at the code.)

> You do need a high level mental model of the system.

That is extremely time-consuming to build without code comments and documentation, regardless of how "literate" the code is, because code alone can not express sufficiently detailed invariants, and simple logical/atomic operations involve a non-trivial amounts of code. (especially when writing in C).

There's almost nothing I hate more than inheriting a complex uncommented code base and spending hours or days tracing out the code to build a high-level mental model, when instead, with reasonable comments, I could have had that model nearly immediately.

The beauty of literate programming, quite honestly, is that because of the way that the documentation and code are interwoven, it requires fewer code comments, and encourages both clear code and clear documentation.
That code you linked has lots of comments containing lots of information. How is this an example of how Senior Programmers are against comments?
Maybe I haven't read K&R carefully enough but how can you have a function declaration like

    sleep(chan, pri)
without any data types?
Because the default datatype is int:-

  $ cat z.c
  foo( a, b )
  {
          return( a+b );
  }
  
  main( void )
  {
          return( foo( 3, 4 ) );
  }
  $ gcc z.c
  $ ./a.out
  $ echo $?
  7