I just came across this article from 2005 written by Jef Raskin (probably most famous for having initiated the Macintosh project at Apple) on source code documentation . I agree with much of what he recommends. I have never believed that code can be “self-documenting” without comments, and generally will start writing the comments before I start the actual code. I also like some aspects of Knuth’s “literate programming” concept .
I do find automatic documentation generators useful, however. There aren’t a lot of solutions for modern Fortran projects though. I’ve not tried to use Doxygen, but am told that support for modern Fortran features is somewhat lacking . ROBODoc is pretty good, although it does not perform any code analysis, and only extracts specific comment blocks that you indicate in the source. A brand new tool called ford is very promising, since it was created with modern Fortran in mind.
I also have an idea that the best code (including comments) should be understandable to a reasonably intelligent person who is not familiar with the programming language. Some languages (Fortran, Python) make this easier than others (C++, Haskell). There is a good article here, discussing the “beauty” of some C++ code (although I disagree with his views on comments). I was struck by the discussion on how to write functions so that more information is provided to the reader of the code . The example given is this:
int idSurface::Split( const idPlane &plane, const float epsilon, idSurface **front, idSurface **back, int *frontOnPlaneEdges, int *backOnPlaneEdges ) const;
Of course, if you are not familiar with the C++
& characters and the
const declaration, there is no information you can derive from this. It is complete gibberish. Modern Fortran, on the other hand, provides for the declaration of an
intent attribute to function and subroutine arguments. The equivalent Fortran version would look something like this:
integer function split(me,plane,eps,front,back,& frontOnPlaneEdges,backOnPlaneEdges) class(idSurface),intent(in) :: me type(idPlane), intent(in) :: plane real, intent(in) :: eps type(idSurface), intent(out) :: front type(idSurface), intent(out) :: back integer, intent(out) :: frontOnPlaneEdges integer, intent(out) :: backOnPlaneEdges
Here, it should be more obvious what is happening (for example, that
plane is an input and
front is an output). The use of words rather than symbols definitely improves readability for the non-expert (although if taken to the extreme, you would end up with COBOL).
- J. Raskin, “Comments are More Important than Code“, Queue, Volume 3 Issue 2, March 2005, Pages 64-65.
- D. E. Knuth, “Literate Programming“, The Computer Journal (1984) 27 (2): 97-111.
- F03/08 supporting Documentation tools, comp.lang.fortran.
- S. McGrath, “The Exceptional Beauty of Doom 3’s Source Code“, kotaku.com, Jan. 14, 2013.