Hacker News new | ask | show | jobs
by ori_b 5050 days ago
> 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.)

3 comments

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.

You want some sort of design document. Comments are not sufficient to describe the way that the concepts interconnect. They are almost always detail oriented, scattered and do not give the big picture.

Comments embedded in source code are singularly unsuited to giving the sort of interconnection of concepts that allows you to quickly and efficiently understand build a model of the system. They are a poor substitute for real documentation.

Something like this should always be present to describe the overarching structure of the system: ftp://gcc.gnu.org/pub/gcc/summit/2003/GENERIC%20and%20GIMPLE.pdf http://gcc.gnu.org/onlinedocs/gccint/RTL.html

Incidentally, I'm not sure if you're familiar with literate programming. That's where the code is almost an afterthought to the comments. This is an example of a literate program: http://tug.org/texlive/devsrc/Build/source/texk/web2c/tex.we.... You may be familiar with it -- it's tex, the core engine used by LaTeX. Compiled to PDF, the source looks like this: http://eigenstate.org/tmp/tex.pdf.

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