[net.lang.c] Style, readability, etc.

DHowell.ES@Xerox.ARPA (07/23/85)

It looks like it's time for me to bring another controversial message
into this mess.


Here is my basic opinion:  Programs should be as readable as possible so
that people who need to look at the code can understand it easily.  If a
program is harder to read, it is harder to understand, and thus harder
to change, debug, update, or whatever.  

The harder a program is to change, the longer it takes.  And the time
wasted in trying to figure out how a program is working, (this could be
someone else's program, or it could be a program that you wrote months
or years ago) is probably more time that the time it would have taken to
make the program more readable.

---Concerning readability---

I have stated that i = i + 1 was more readable than i++.  The reason is
that i = i + 1 is a standard seen in many languages (only the assignment
operator has been changed to protect the computer scientists).  I have
even seen the machine language operator INC A defined as A <- A + 1.
Just as readable (or even more so) is "increment i", seen in some
languages in some form or another.  But C comes up with i++ and ++i and
confuses the issue by coming up with three different ways of
incrementing a variable.  Seems to me only one is necessary.  "++" is
unique to C; I have never seen it in any other language.  The symbol
does not mean anything to anyone not versed in C, rather, it was
invented by the implementors of C to make things easier to type and
compile.  Now everyone says that anyone who knows anything about C knows
what "++" means, and yes that is true.  So if you must use your precious
"++" then go ahead, but make sure your comments explain what you're
doing.  The comment

  i++;  /* increment i */

has been called a non-comment, and it is for C programmers, but if any
non-C programmer needs to look at it (which you say never happens, but
I'm sure it happens more than you think) it is helpful.  But even more
helpful even for C programmers is a comment explaining why you are
incrementing the variable, such as

  fish++;  /* we found another fish, so increment the fish counter */
 
  ptr++;  /* increment the pointer to the next element */
  
  while(ptr++->duck)  /* move pointer to the duck after the next NULL */
    ;

That last one is equivalent (in purpose) to

  while( ptr->duck != NULL )  /* move pointer to next NULL duck */
    ptr = ptr + 1;
  ptr = ptr + 1;              /* and increment to the one after it */

This form is more readable, but if efficiency is your thing, then the
first one is ok *AS LONG AS THE COMMENT IS THERE*.

And don't worry about efficiency until the program works!

The main problem I have with i++ and other such is that many programmers
do not comment their code enough, and i++, or even worse a?b:c (which
has been talked about a lot but its readability has not been discussed)
just makes the code harder to read.

To demonstrate, I am currently working on a program, written by someone
else, written in Mesa, a language similar to Pascal, but much more
modular.  The language is very readable as languages go.  The program
has very few comments.  (The majority of comments are the kind "END;
--of DisplayProc"; really helpful, eh?)  I think how much easier the
program would be to understand if it had comments.  But then I think how
much harder it would be to understand if it were written in C (without
comments).  But comments written in English explaining it all (not just
the top level but the details too) would help in any programming
language and I would be able to spend more time writing my own programs
than deciphering others' programs.  After all I thought we are hired as
programmers to write programs.

---Concerning professionalism---

If you are a programmer writing an accounting program, at least one of
two things has to happen:  The programmer must learn something about
accounting, or the accountant must learn something about programming.
This is true any time two professions must work together.   Each one can
make it easier for the other by doing their part make things more
understandable.  This is true professionalism, when one can work with
the other without too much difficulty.  Too many programmers seem to
believe that professionalism means just the opposite:  being able to be
understood only by one's own profession.  This mistaken belief leads us
into misunderstandings all over the place.  And misunderstanding is not
a good thing, especially when your trying to get something done.

Dan

chris@umcp-cs.UUCP (Chris Torek) (07/23/85)

[ { :-) ]

Mesa, "highly readable"?  The keywords are in all caps!  Yucko!

(But at least it lets one use {, } for BEGIN, END.)

[ } ]

Actually, the biggest problem I've had writing (not debugging,
creating) Mesa code is following the profusion of derived types.
Bitblt wants a BBptr which points to a Block which is an array of
Environment.Byte which... well, you probably get the idea.  It
takes three manuals open to six different places simultaneously
until you've learned the more common types.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 4251)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@maryland

moss@BRL.ARPA (Gary S. Moss (AMXBR-VLD-V)) (07/23/85)

HEH!  We all know that readability is important and of course comments,
when done right are vital to readable code.  The problem is that i++ has
nothing to do with unreadable code and could you please get off of it already?

STOP BEATING THAT POOR DEAD HORSE!
-moss

jss@sjuvax.UUCP (J. Shapiro) (07/24/85)

[Aren't you hungry...?]

Dan, I believe that you are saying something which is terribly
important, but I disagree very strongly with your examples, as I
believe that they contradict your point.

> Programs should be as readable as possible so
> that people who need to look at the code can understand it easily.  If a
> program is harder to read, it is harder to understand, and thus harder
> to change, debug, update, or whatever.

I agree completely, but starting immediately hereafter we disagree.

> But C comes up with i++ and ++i and
> confuses the issue by coming up with three different ways of
> incrementing a variable.  Seems to me only one is necessary.

These two operators perform significantly different functions which
enable the writing of tight code which is not (granted, to a C
programmer) obfuscated.  Indeed, many C programmers would find the
code which would be necessary to avoid these constructs in certain
places terribly indirect and confusing, which in some places it is.  I
too have used pascal and its brethren, and I believe that for some
tasks they are incredibly useful.  I prefer C for most applications
because of its flexibility of expression and its more sensible pointer handling.  Appropriately, my commenting
style varies in accordance with the language I am using.

> Now everyone says that anyone who knows anything about C knows
> what "++" means, and yes that is true.

If I understood you, your complaint here is that the arbitrary person
doesn't know about "++".  Your underlying implication here is that
programming languages should cater to the public's knowledge even at
cost of expressive flexibility.  To this I take exception.  A
programming language must strike a balance between expressive
flexibility to the programmer and legibility to the programmer and the
programmer's successors.  I am not convinced that my present employer,
who is a lawyer, should be able to read the code with no background
whatsoever, just as I cannot read or write contracts with full
understanding in the case of an adequately complex contract.  I am
firmly convinced that the code should be readable to another
programmer, and even to a fairly new C programmer, but if my employer
wants to read the code I feel that it is reasonable to insist that he
be willing to use the index of K&R, which is not long, or ask me about
whatever questions he may have.  The time and effort that this costs him
is substantially less than the time which lack of expressive flexibility
in the language would cost both of us.  Both of us are making a commitment.
I am making one to writing quality code within a time limit which
will be easily understood by anyone familiar with the language in question
with effort which is in proportion to the complexity of the task. My
employer is making a commitment not to hamper my efectiveness in performing
his task within the pre-established limits of budget, time, and human
tolerance.  He has every right to set INFORMED standards, and I
welcome his suggestions because they almost always give me better
insight into how to accomplish his task, but if his standards are
arbitrarily, unreasonably, and uninformedly applied, I will not work for
him, and neither will most other people I know.

I cannot think of any language which is easily readable to the general
uneducated public, including English.  Any demand which deprives me of
flexibility of necessity obfuscates my work, and makes that work
harder to accomplish. This is not in my or my employer's best interests.

> But even more
> helpful even for C programmers is a comment explaining why you are
> incrementing the variable, such as

> fish++;  /* we found another fish, so increment the fish counter */

I tend to prefer a block of comment describing the theory of operation
of the following section of code, and listing with the declaration of
each variable (other than i, j, and k, which I use exclusively for
loop control) its use.  This is more useful to a non computer type
than the individual comment, and is much more informative to the
experienced programmer than the disjoint comments.  It enables the
programmer to look at the code, know what it should do, and find the
broken case(s), which with disjointed comments is much more
difficult.  Comments need to be used selectively, so as to inform
without being condescending or extraneous.  Too much commenting is as
bad as too little, because it detracts from the attention that a
programmer or reader will apply to the comments in reading the code.
For example:
 
> ptr++;  /* increment the pointer to the next element */

This comment certainly does not tell the programmer of C anything, and
tells the novice nothing as well.  What the hell is a pointer,
anyway?  A pascal programmer can reasonably be expected to know
something about operators and computer languages, and to be smart
enough to look at whatever book is appropriate for reading a "foreign"
language.  Any programmer who is unwilling to do this is not being
responsible.
  
> while(ptr++->duck)  /* move pointer to the duck after the next NULL */
>   ;

This one is even more obscure than the last.  I am a C programmer, and
this tells me nothing - indeed it is dead wrong, as it simply will not
happen as the comment might lead me to believe.  This will leave me
with ptr pointing to the next available record whose element named
duck is 0.  It certainly has nothing to do with NULL or anything after
duck.  This is one of the major difficulties with such comments.
There is a tendency even among experienced programmers to read them
and believe them, and thereby not see an obvious difficulty.  On the
other hand, the comment does reveal to me that the author either
didn't have the foggiest notion about while termination (which in this
case seems unlikely) or was in another universe when he wrote the
comment.  This tells me that the program probably needs fundamental
rethinking, and is therefore only nominally useful.  Of course, if the
programming needs such rethinking, I most likely had already figured
that out on the basis of poor coding.

Your idea that things should be clear is correct, but I believe that
your opinions on what constitutes clarity could use further
examination.  I have never had anyone complain about the clarity of my
C code, and I have written many thousands of lines. I find that the
approach I teach leads my students to a much better understanding of problem
solving approach, which usually leads to superior results.  This is
becaus e the commenting style I advocate requires clear understanding
of the problem to effect properly. I certainly do not have the ideal
approach, nor do I believe that there is any such thing.  You might find
Kernighan and Plaugher's book _The Elements of Programming Style_ helpful,
though I have my disagreements with them as well.

Ultimately, I find that the clarity of the code produced correlates
directly with the programmer's understanding of the problem
constrained by the programmer's understanding of the language and the
programmer's overall competence.

I am sure you will receive other responses to your comments, and I
would welcome discussing this, but I suggest that further discussion
be conducted by mail.

Jonathan S. Shapiro
Haverford College
..!sjuvax!jss

tmb@talcott.UUCP (Thomas M. Breuel) (07/26/85)

> Here is my basic opinion:  Programs should be as readable as possible so
> that people who need to look at the code can understand it easily.  If a

Great. I love readable programs. Why don't you start indenting by
8 spaces, put your braces on the same line as the conditional, and
make frequent use of '++' and if((c=getchar())!='\n'). And don't use
comments.

Seriously, readability is a purely personal matter. I vastly prefer
programs that are dense, i.e. in which I can see lots of code on a
single page. Other people prefer explanatory comments and to balance
their braces by putting them on individual lines.

> I have stated that i = i + 1 was more readable than i++.  The reason is
> that i = i + 1 is a standard seen in many languages (only the assignment

The expression (sic) 'i=i+1' is wrong if you consider it from a mathematical
point of view (i.e. grammar school math), but you nevertheless got so
used to it that you consider it 'readable' and 'natural'. This shows
that you (and probably others) are pretty flexible in terms of syntax.

>   while(ptr++->duck)  /* move pointer to the duck after the next NULL */
>     ;
> [...] 
> but if efficiency is your thing, then [this] one is ok 
> *AS LONG AS THE COMMENT IS THERE*.

You present the example of an idiom that is taught (or should be taught)
to any beginner in 'C'. Understanding a programming language does not
mean that you only understand its syntax or its semantics, but that you
also know its idioms by heart, much as you don't 'speak' a natural language
until you understand its idioms and figures of speech without explanatory
remarks. (BTW, I DON'T LIKE isolated semicolons, I find that they are
BAD STYLE... Also, your comment doesn't make much sense to me,
whereas your code does).

> And don't worry about efficiency until the program works!

Agreed, that's perfectly reasonable. But programmers (at least the
ones I know) don't use compact notation in 'C' because they think
it is more efficient (sometimes it is not), but because it expresses
things concisely.

> To demonstrate, I am currently working on a program, written by someone
> else, written in Mesa, a language similar to Pascal, but much more
> modular.  The language is very readable as languages go.  The program
> has very few comments.  (The majority of comments are the kind "END;
> --of DisplayProc"; really helpful, eh?)  I think how much easier the

Understanding someone else's code is always work. I like code most
which describes the purpose, input, output, and side-effects of each
procedure but comments procedure bodies only very sparsely. But,
again, that is a matter of opinion, not of absolute truth.

Altogether: understanding someone else's program is always work. It
is easier if that person happens to have the same programming style
that you do. Usually that is not the case. Don't curse other people
for using what they consider the best way to layout their programs,
they probably have good reasons for it.

Now, you can start discussions about whether it is better to indent
by three or by eight spaces, whether it is better to balance braces
with braces or control statements, whether it is better to use this
or that idiom, and so on, but you are likely not to find much sympathy
and not to have too much success to generate a standard.

						Thomas.

PS: Personally, I am in the lucky position that a like 'cb', that I know
'sed', and that I dislike comments, and that I therefore can put
programs into 'my style' rather easily (it is easy to remove comments
automatically, but hard to add them...).

peter@baylor.UUCP (Peter da Silva) (07/26/85)

> ++ is unique to C; I have never seen it in any other language.

	FORTH:		1+!
	PDP-11 as:	mov	(sp)+,port
	6809 as:	leas	,x++

> The symbol
> does not mean anything to anyone not versed in C, rather, it was
> invented by the implementors of C to make things easier to type and
> compile.

	It was invented by the DESIGNER of 'C' because it served
a useful purpose. The syntax "a <- +/array" was invented by the
DESIGNER of apl because it served a useful purpose. The syntax
(cond (t blah...)) was invented by the DESIGNER of LISP because
it served a useful purpose. The syntax "a in ['0'..'9']" was
invented by the DESIGNER or Pascal because it served a useful
purpose.

	Every language has idioms. Why are you picking on a relatively
harmless one in 'C'?

> non-C programmer needs to look at it (which you say never happens, but
> I'm sure it happens more than you think) it is helpful.

	Any non-c programmer is going to have to learn more about the
language than just ++. What about for(init;test;inc)? Does that make
sense without studying Kernighan & Ritchie? Or continue (what does that
do to a Fortran hack)... if we're going to have to comment everything
'C' does that some other language doesn't we might as well write in
COBOL. What do you think about COBOL, by the way?

>   while(ptr++->duck)  /* move pointer to the duck after the next NULL */
>     ;
> 
> That last one is equivalent (in purpose) to
> 
>   while( ptr->duck != NULL )  /* move pointer to next NULL duck */
>     ptr = ptr + 1;
>   ptr = ptr + 1;              /* and increment to the one after it */
> 
> This form is more readable, but if efficiency is your thing, then the
> first one is ok *AS LONG AS THE COMMENT IS THERE*.

I don't find one or the other particularly less readable. The second one
makes me want to scream...

> To demonstrate, I am currently working on a program, written by someone
> else, written in Mesa, a language similar to Pascal, but much more
> modular.  The language is very readable as languages go.  The program
> has very few comments.  (The majority of comments are the kind "END;
> --of DisplayProc"; really helpful, eh?)  I think how much easier the
> program would be to understand if it had comments.  But then I think how
> much harder it would be to understand if it were written in C (without
> comments).

Since some turkey wrote a program in some obscure language that looks like
ADA, and didn't comment it, you got a bee in your bonnet about comments and
decided to take it all out on us.
-- 
	Peter da Silva (the mad Australian)
		UUCP: ...!shell!neuro1!{hyd-ptd,baylor,datafac}!peter
		MCI: PDASILVA; CIS: 70216,1076

mauney@ncsu.UUCP (Jon Mauney) (07/26/85)

> From: jss@sjuvax.UUCP (J. Shapiro)
> Subject: Re: Style, readability, etc. (long, but IMPORTANT)
> Message-ID: <1207@sjuvax.UUCP>
>   
> > while(ptr++->duck)  /* move pointer to the duck after the next NULL */
> >   ;
> 
> This one is even more obscure than the last.  I am a C programmer, and
> this tells me nothing - indeed it is dead wrong, as it simply will not
> happen as the comment might lead me to believe.  This will leave me
> with ptr pointing to the next available record whose element named
> duck is 0.  It certainly has nothing to do with NULL or anything after
> duck.  This is one of the major difficulties with such comments.
> There is a tendency even among experienced programmers to read them
> and believe them, and thereby not see an obvious difficulty.
> 
> Jonathan S. Shapiro
> Haverford College
> ..!sjuvax!jss
> 

Let me first point out that I agree that block comments are generally
more useful than end-of-line comments.  However, there are many places
in which an end-of-line comment is very useful.  The present example
is one, as proved by the fact that apparently experienced C programmers
cannot agree on the effect of the loop.  Code that is so susceptible to
error should be avoided or heavily commented.

I look at comments as recording the programmer's *intent*, whereas the
code is (obviously) what he actually *did*.  Reading the comments tells
me whether the bug is likely due to a poor design.  If the design
seems sound, then I look for discrepancies between code and comments.
Any such discrepancy is a clear indication of a problem, although the
problem may be as simple as a slip of the mind.  Comments add redundancy
to a program, and redundancy is A Good Thing, in moderation.
-- 

Jon Mauney,    mcnc!ncsu!mauney       "The door's not shut on my genius, but...
North Carolina State University        I just don't have the time."

tien@ncr-sd.UUCP (Tien Nguyen) (08/08/85)

In article <95@brl-tgr.ARPA> DHowell.ES@Xerox.ARPA writes:
>But even more helpful even for C programmers is a comment
>explaining why you are incrementing the variable, such as
>
>  fish++;  /* we found another fish, so increment the fish counter */
> 
>  ptr++;  /* increment the pointer to the next element */
>  i++;  /* increment i */
>
The first comment is 'good' since it explains why we want to increment
the fish counter--found another fish.  However, the next two comments
are irrelevant.  The reason is if the reader does not know what i++
means then he/she could always look at any C book once and from then
on he/she will know that i++ is i=i+1 thus we don't need to add the
comment /* increment xx */ all over our program.  However, the comment,
if any, should explain why we want to increment i or ptr.

In my opinion, the comment should tell the reader WHY and WHAT we are doing
rather than to explain the language syntax.  I would have put the same
comment on the fish++ statement even if I wrote it in form:

			fish = fish + 1;


					Tien Nguyen,