[comp.lang.c] Proposal for a scientific look at C style choices

eric@snark.UUCP (Eric S. Raymond) (12/23/88)

The recent (remarkably civil) discussion oF C layout styles has piqued my
curiosity. I want to ask comp.lang.c's help in taking a real, analytical look
at the quesion of why people lay out C code the way they do.

C code layout is a classic example of rule-governed behavior in which the rules
are inexplicit and often less than half-conscious, but evidently very strong.

What I'd like to do is work out something like a decision tree or graph that
has coders' value choices about various aesthetic issues as arcs and various
described coding styles or coding style classes as nodes -- a sort of
functional taxonomy of coding styles.

To illustrate the approach I have in mind, consider the distinction between
"comb-style" and "block-indented" switch layouts:

switch (val)  /* comb style */           switch (val) /* block-indented */
{                                        {
case VAL1:                                       case VAL1:
        /* stuff */                                      /* stuff */
        break;                                           break;
case VAL2:                                       case VAL2:
        /* more stuff */                                 /* more stuff */
        break;                                           break;
default:                                         default:
        /* yet more stuff */                             /* yet more stuff */
        break;                                           break;
}                                        }

(The reader may prefer a different indent depth, or may not put the opening
bracket on its own line. In this context, these are details)

Now, I *think* that the "comb" versus "block" choice hangs on a question
that goes something like this:

Question S: are you willing to make an exception to the global rule that the
contents of a control block is indented one level deeper than the "sentinel"
part in order to make switches look more like jump tables, or to reduce their
cost in visual nesting depth?

If I'm right, this is one node in the ur-graph of C styles I'm after. The
interesting question: are there other, *fundamentally different* criteria on
which this choice can be made? If so, what are they? 

Consider, also, that in one major style (Whitesmiths) it is natural to write:

switch (val)
    {
    case VAL1:
            /* stuff */
            break;
    case VAL2:
            /* more stuff */
            break;
    default:
            /* yet more stuff */
            break;
    }

but that

switch (val)
    {
case VAL1:
        /* stuff */
        break;
case VAL2:
        /* more stuff */
        break;
default:
        /* yet more stuff */
        break;
    }

appears to be quite rare and strikes most C programmers as unnatural, even
though it's the logical combination of "comb" and Whitesmiths style. What
rules are operating here? I can guess, but then I *know* what my rules are;
I'm curious about other peoples'.

Let's start by mapping a really major node. Maybe the most basic question
in C layout is:

Question A: Which do you value more; conservation of vertical space, or a
global rule that start braces go at the same visual indent level as their end
braces?

If your answer is "value conservation more", then you are likely to use
Kernighan & Ritchie style:

if (cond) {
     /* stuff */
}

If you value visual symmetry more, then you are likely to use one of the
other two major style classes:

if (cond)    /* Whitesmiths style */
        {
        /* stuff */
        }

or

if (cond)     /* BSD or "Neo-Pascal-oid" style */
{
       /* stuff */
}

I think the tension between these is captured by:

Question B: in control structures, do you consider the braces to be more
firmly glued to a) the "guard" part, or b) the enclosed statement(s).

If your answer to "B" is a), you're likely to plump for the Pascal-oid layout.
If it's b), you probably like some Whitesmiths variant. I *think*. I'm inviting
comment on all this.

This is a kind of investigation the net ought to be perfectly suited to. At
the very least, maybe we could develop a useful standard terminology for
the major layout styles. (For example, I'm very sure the Berkeley crew used
more than one layout style; I'd like a better term for what I've called "BSD"
layout, particularly since it's what I happen to use).

Once we've mapped the "style graph" we can use the net to make something like a
scientific survey of usage frequencies, correlations with various "programming
cultures", etc. Real knowledge could come out of this!

Criticisms and suggestions for improvement of my terminology, my proposed
A, B and S nodes, and anything else I've raised here are welcome. Well-thought
out descriptions of other key decision points wouuld be even more welcome.
-- 
      Eric S. Raymond                     (the mad mastermind of TMN-Netnews)
      Email: eric@snark.uu.net                       CompuServe: [72037,2306]
      Post: 22 S. Warren Avenue, Malvern, PA 19355      Phone: (215)-296-5718

bill@twwells.uucp (T. William Wells) (12/24/88)

In article <eWl9H#2cdgbS=eric@snark.UUCP> eric@snark.UUCP (Eric S. Raymond) writes:
: Let's start by mapping a really major node. Maybe the most basic question
: in C layout is:
:
: Question A: Which do you value more; conservation of vertical space, or a
: global rule that start braces go at the same visual indent level as their end
: braces?
:
: If your answer is "value conservation more", then you are likely to use
: Kernighan & Ritchie style:
:
: if (cond) {
:      /* stuff */
: }

I believe that there is an alternate rationale for the above style:
that braces exist only to make the compiler happy and should therefore
be as unobtrusive as possible. This is why I use the above; I recall
dmr saying that that is his reason as well.

However I do value conservation of vertical space. Which is why, for
the purposes of deciding whether a blank line should be inserted, I
consider a line containing a brace to be equivalent to a blank line.

: Question B: in control structures, do you consider the braces to be more
: firmly glued to a) the "guard" part, or b) the enclosed statement(s).
:
: If your answer to "B" is a), you're likely to plump for the Pascal-oid layout.
: If it's b), you probably like some Whitesmiths variant. I *think*. I'm inviting
: comment on all this.

I consider the braces as a separate element: sometimes necessary for
the compiler (but I always use the braces), but contributing little or
nothing to the understandability of the program.  The indentation of
the program is what tells you the control relationships; the braces
are redundant information, at best they can augment what the
indentation is alreaddy telling you.

---
Bill
{uunet|novavax}!proxftl!twwells!bill

mat@mole-end.UUCP (Mark A Terribile) (12/27/88)

> C code layout is a classic example of rule-governed behavior in which the
> rules are inexplicit and often less than half-conscious, but evidently very
> strong.

> [I'd like to] work out ... a decision tree or graph that has coders' value
> choices about various aesthetic issues as arcs and various described coding
> styles or coding style classes as nodes -- a ... functional taxonomy ....

<switch() statement layout examples>

> Now, I *think* that the "comb" versus "block" choice hangs on a question
> that goes something like this:
> 
> Question S: are you willing to make an exception to the global rule that the
> contents of a control block is indented one level deeper than the "sentinel"
> part in order to make switches look more like jump tables, or to reduce their
> cost in visual nesting depth?

I will offer another decision that must be made: is the ``sentinel'' part
a monolith, or does it have multiple levels as well?

I indent the case labels by two spaces on the belief that they are easier to
see that way (I use 8-space indents) and on the belief that the control
(sentinel) is not a monolith.  Likewise, I generally write

	if(    a->op == XNES_step
	    && a->size <= XNES_bufsize
	 ||    a->op == XNES_fix
	    && a->size + a->leftover <= XNES_bufsize )
	{
		. . .
 
> If I'm right, this is one node in the ur-graph of C styles I'm after. The
> interesting question: are there other, *fundamentally different* criteria on
> which this choice can be made? If so, what are they? 

Visual presentation, for one.  I like to be able to look at a piece of code
three feet away and know where the different chunks of code begin and end,
and upon which ``splinters'' the various chunks depend.  (I'm a charter member
of The Committe to Keep Whitespace White :^> )

Oh, and I prefer to see my text printed in portrait mode using a fixed-width
``typewriter'' font by a high-res (laser or electrostatic) printer.

> Question B: in control structures, do you consider the braces to be more
> firmly glued to a) the "guard" part, or b) the enclosed statement(s).

Neither.  They are an adapter between the ``guard'' which controls single
statements and the group of statements which often need to be controlled
together.
-- 

(This man's opinions are his own.)
From mole-end				Mark Terribile

nevin1@ihlpb.ATT.COM (Liber) (12/28/88)

In article <272@twwells.uucp> bill@twwells.UUCP (T. William Wells) writes:

>I consider the braces as a separate element: sometimes necessary for
>the compiler (but I always use the braces), but contributing little or
>nothing to the understandability of the program.

If the braces are necessary for the compiler (which they sometimes
are), then they do contribute to the understandability of the program.
Otherwise they wouldn't be necessary!

>The indentation of
>the program is what tells you the control relationships; the braces
>are redundant information, at best they can augment what the
>indentation is alreaddy telling you.

I feel the opposite is true (indentation provides the redundant
information, not the braces).  If the braces are wrong, my program
probably won't do what I intended it to do.  If the indentation is
wrong, my program can still compile and run correctly.  Indentation are
like comments in that there is nothing to enforce them being correct.
For maintaining other people's code, I can only rely on the same things
that the compiler relies on (in this case, the braces instead of the
indentation).
-- 
NEVIN ":-)" LIBER  AT&T Bell Laboratories  nevin1@ihlpb.ATT.COM  (312) 979-4751

ddb@ns.UUCP (David Dyer-Bennet) (12/30/88)

In article <132@mole-end.UUCP> mat@mole-end.UUCP (Mark A Terribile) writes:
:Likewise, I generally write
:
:	if(    a->op == XNES_step
:	    && a->size <= XNES_bufsize
:	 ||    a->op == XNES_fix
:	    && a->size + a->leftover <= XNES_bufsize )
:	{
:		. . .

I've long had a pet theory that, for every legal point at which a line
could be broken, there is a "correct" indent for the resulting continuation
line.  It looks like you may have some similar strange ideas.  

However, your strange idea violates one of MY basic concepts of code
formatting: indentation is something that takes place between the left
margin and the first character on the line, NOWHERE ELSE.  (Flame
retardant: this is my opinion; this is ONLY my opinion.  If this had
been objective reality, you would have done it my way and we wouldn't
be having this discussion.)
-- 
	-- David Dyer-Bennet
	...!{rutgers!dayton | amdahl!ems | uunet!rosevax}!umn-cs!ns!ddb
	ddb@Lynx.MN.Org, ...{amdahl,hpda}!bungia!viper!ddb
	Fidonet 1:282/341.0, (612) 721-8967 hst/2400/1200/300

ddb@ns.UUCP (David Dyer-Bennet) (12/30/88)

In article <eWl9H#2cdgbS=eric@snark.UUCP> eric@snark.UUCP (Eric S. Raymond) writes:
:switch (val)  /* comb style */           switch (val) /* block-indented */
:{                                        {
:case VAL1:                                       case VAL1:
:        /* stuff */                                      /* stuff */
:        break;                                           break;
:}                                        }
:
Actually, the problem *I* have with comb style, other than unfamiliarity,
is that I can't find the end of the switch body by scanning for the next
character at the level of the switch.  (I find scanninng for ANY character
a much faster operation than scanning for a "}" specifically).  Your block
indented style also has this problem -- I get hung up on the openning brace.
Which is why I do K&R style brace placement.  My personal weirdness here
is to move the indentation of the "break" back OUT to be directly under the
"case"; essentially treating it as a closing delimiter.  Once again this
is motivated by wanting to find the end of the current block by scanning
down for the first thing directly under the start of the current block.
Thus we get:

switch (val) {			/* dd-b style */
    case VAL1:
	/* stuff */
    break;			/* case VAL1 */
    ...
}				/* switch val */

:but that
:
:switch (val)
:    {
:case VAL1:
:        /* stuff */
:        break;
:    }
:
:appears to be quite rare and strikes most C programmers as unnatural, even
:though it's the logical combination of "comb" and Whitesmiths style. What
:rules are operating here? I can guess, but then I *know* what my rules are;
:I'm curious about other peoples'.

This violates a VERY low-level rule, namely that things should never be
indented less than the level they started at.  Once you indent that first
brace, you can't place anything to the left of it until you hit the closing
brace.  That seems to be true in all major programming styles.  It's certainly
basic to mine (as mentioned above, I want to scan down for the first character
under the block start to find the block end).

:Let's start by mapping a really major node. Maybe the most basic question
:in C layout is:
:
:Question A: Which do you value more; conservation of vertical space, or a
:global rule that start braces go at the same visual indent level as their end
:braces?

I value conservation of vertical space highly, but I don't have the
rule about braces you propose.  I tend to agree with the poster who
said that braces are necessary only because the compiler isn't smart
enough to interpret block structure from the indentation.  Has anybody
played with such a compiler, by the way?  Or a checker for C which
would complain if the actual block structure didn't match that implied
by indentation?

:Question B: in control structures, do you consider the braces to be more
:firmly glued to a) the "guard" part, or b) the enclosed statement(s).

Either to the guard part, or else I regard them as a separate entity.
This, of course, is contrary to the language definition, but it makes
for more readable code.  (No, this isn't the style I first learned in
a structured language.  This is about my third stylistic obsession.)

I think of 
    if (cond) {
	/* stuff */
    }
as one statement, so I like having it begin and end at the same indent
level.  Also, if there happens to be white space or an end of page
after the closing brace, having that brace at "if" level is the only
way to put something at that level to stop my eye before it scans on down.

-- 
	-- David Dyer-Bennet
	...!{rutgers!dayton | amdahl!ems | uunet!rosevax}!umn-cs!ns!ddb
	ddb@Lynx.MN.Org, ...{amdahl,hpda}!bungia!viper!ddb
	Fidonet 1:282/341.0, (612) 721-8967 hst/2400/1200/300

mat@mole-end.UUCP (Mark A Terribile) (01/02/89)

In article <1045@ns.UUCP>, ddb@ns.UUCP (David Dyer-Bennet) writes:
> :Likewise, I generally write
> :
> :	if(    a->op == XNES_step
> :	    && a->size <= XNES_bufsize
> :	 ||    a->op == XNES_fix
> :	    && a->size + a->leftover <= XNES_bufsize )
> :	{
> :		. . .
> 
> However, your strange idea violates one of MY basic concepts of code
> formatting: indentation is something that takes place between the left
> margin and the first character on the line, NOWHERE ELSE.

Hmm.  Do you mean that you have never written

#if ...

#  if ...
. . .
#  else
. . .
#endif

Yes, I am breaking my own rules about tabstop indents!  It seems so desirable
to keep the preprocessor stuff visible at the begining that I'm willing to
go to two-space indents.  On the other hand, I read the preprocessor stuff
about one thirtieth (numeric value generated by scientific hand waving) as
often as I do the code which is compiled into object, and so I am willing to
take a slight cost in readability.

My criterion is communication: how well does the typographical layout of the
code on the page communicate the organization of the code?  (See the example
on p. 23 of Kernighan and Plauger, *The Elements of Programming Style*.)

Does the example first given carry the principle too far?  Having waded
through thousands of lines of code whose lines were broken where nroff would
break them and whose authors evidently thought more levels of parentheses
were better ways of communicating to the reader than typography, I think that
the principle is NOT carried to far, if only because it serves to inspire
people working with me to improve a little.  As it might have been written:

	if(((a->op==XNES_step)&&(a->size<= XNES_bufsize))||((a->op==XNES_fix
		)&&((a->size+a->leftover)<=XNES_bufsize)))

(Ok, even nroff wouldn't have put the ``)'' at the beginning of a line.  I
have seen it done by programmers, however.)

> (... this is ONLY my opinion.  If this had been objective reality, you would
> have done it my way and we wouldn't be having this discussion.)

You better *smiley* when you say that, son ;'[  ;^}
-- 

(This man's opinions are his own.)
From mole-end				Mark Terribile

geoff@endor.harvard.edu (Geoff Clemm) (01/03/89)

In article <9279@ihlpb.ATT.COM> nevin1@ihlpb.UUCP (55528-Liber,N.J.) writes:
>In article <272@twwells.uucp> bill@twwells.UUCP (T. William Wells) writes:
>
>>I consider the braces as a separate element: sometimes necessary for
>>the compiler (but I always use the braces), but contributing little or
>>nothing to the understandability of the program.
>
>If the braces are necessary for the compiler (which they sometimes
>are), then they do contribute to the understandability of the program.
>Otherwise they wouldn't be necessary!

Apparently Bill didn't spell it out in enough detail ... this is the second
posting that uses the logic "if it's good for the compiler, it MUST be good
for a human", a non-sequitur at best (unless you still think coding in octal
is the way to go).

Humans process 2d information extremely well - they are only moderately good
at parsing long strings.  On the other hand, computers are very good at parsing
long strings - they are at best only moderately good at processing 2d 
information.  Indentation completely specifies the grouping.  If you see

xxxxx
   xxxxx
   xxxxxxx
xxxxx

and need this :

xxxxxx
   {
      xxxxxx
      xxxxxxxx
   }
xxxxx

to tell you that the second two lines are nested between the first and last,
your visual processing hardware is severely damaged.  On the other hand, the
computer lacks this processing hardware, and so the easiest thing is to provide
the bracket fluff to make its job easy.  To minimize the disruptive
influence on the human's 2d processing, bracket placement should minimize its
2d visual obtrusiveness.

> ... If the braces are wrong, my program
>probably won't do what I intended it to do.  If the indentation is
>wrong, my program can still compile and run correctly.  Indentation are
>like comments in that there is nothing to enforce them being correct.
>For maintaining other people's code, I can only rely on the same things
>that the compiler relies on (in this case, the braces instead of the
>indentation).

With the virtually universal availability of formatting tools (such as
indent, cb, etc, etc) and editors that auto-indent your code as you write
it (such as emacs), this argument has as much weight as arguing that
lines should have sequence numbers so that if you drop your card deck,
it is easy to get the statements back in order.

Geoff

fransvo@htsa.uucp (Frans van Otten) (01/03/89)

In article <1046@ns.UUCP> ddb@ns.UUCP (David Dyer-Bennet) writes:
>I think of 
>    if (cond) {
>	/* stuff */
>    }
>as one statement, so I like having it begin and end at the same indent
>level.  Also, if there happens to be white space or an end of page
>after the closing brace, having that brace at "if" level is the only
>way to put something at that level to stop my eye before it scans on down.

I don't like the begin and the end at the same indent level. The indent
level where the statement begins is where I expect the next statement to
start. So I always write code like this:

  if (cond)
    { ...
      ...
    }
  nextstatement;

You might say I use a 'half indent' (two spaces) for the {} and a 'full
indent' (four spaces) for the actual code. So I have something to stop
my eye at the end of the compound statement.

The compound statement starts on the same line as the opening {, saving
vertical space.  Some people object to this using editing convenience
arguments.  That never was a problem to me, though.

-- 
                         Frans van Otten
                         Algemene Hogeschool Amsterdam
			 Technische en Maritieme Faculteit
                         fransvo@htsa.uucp

conor@inmos.co.uk (Conor O'Neill) (01/05/89)

In article <1046@ns.UUCP> ddb@ns.UUCP (David Dyer-Bennet) writes:
>I value conservation of vertical space highly, but I don't have the
>rule about braces you propose.  I tend to agree with the poster who
>said that braces are necessary only because the compiler isn't smart
>enough to interpret block structure from the indentation.  Has anybody
>played with such a compiler, by the way?  Or a checker for C which

The OCCAM language relies entirely on indentation for its block
structure.  Each level of indentation MUST be 2 spaces.
(Since OCCAM allows nested functions, etc, any more would push everything
off the right hand side).
I find this very useable, especially when combined with a folding editor,
and it makes it very easy to see the block structure.
-- 
Conor O'Neill, Software Group, INMOS Ltd. 
Disclaimer: All views are my own, not those of INMOS.
(UK) JANET: conor@uk.co.inmos      | UUCP:  (...!mcvax!ukc!inmos!conor)
ARPA:       conor@inmos.co.uk      | Phone: +44 454 616616 x 507

ddb@ns.UUCP (David Dyer-Bennet) (01/05/89)

In article <135@mole-end.UUCP> mat@mole-end.UUCP (Mark A Terribile) writes:
:In article <1045@ns.UUCP>, ddb@ns.UUCP (David Dyer-Bennet) writes:
:> :Likewise, I generally write
:> :
:> :	if(    a->op == XNES_step
:> :	    && a->size <= XNES_bufsize
:> :	 ||    a->op == XNES_fix
:> :	    && a->size + a->leftover <= XNES_bufsize )
:> :	{
:> :		. . .
:> 
:> However, your strange idea violates one of MY basic concepts of code
:> formatting: indentation is something that takes place between the left
:> margin and the first character on the line, NOWHERE ELSE.
:
:Hmm.  Do you mean that you have never written
:
:#if ...
:
:#  if ...
:. . .
:#  else
:. . .
:#endif

Well, I understand dpANS allows the "#" to be the first non-blank character
on the line, rather than precisely the first, so this could be done in the
normal obvious way in a compliant compiler.  I believe that that's what I've
done when I nest conditionals (not too often, obviously).

:My criterion is communication: how well does the typographical layout of the
:code on the page communicate the organization of the code? 

Yes, of course.  Obviously you are another Reasonable Person :-).  I think
most of us agree with this.  The problem is, page design is an art not
a science, and essentially none of us are trained in it.  We're going to
come up with different ideas of what communicates the organization best.

:Does the example first given carry the principle too far?  Having waded
:through thousands of lines of code whose lines were broken where nroff would
:break them and whose authors evidently thought more levels of parentheses
:were better ways of communicating to the reader than typography, I think that
:the principle is NOT carried to far, if only because it serves to inspire
:people working with me to improve a little.  As it might have been written:
:
:	if(((a->op==XNES_step)&&(a->size<= XNES_bufsize))||((a->op==XNES_fix
:		)&&((a->size+a->leftover)<=XNES_bufsize)))

There is another option besides your first example, and this example of how
not to do it:  Pick the line breaks for clarity, follow a consistent indenting
rule for each line.  This can be done with indentation strictly at the left.

(Thinking back, I can remember having used a format with internal whitespace
for an algorithm with clear "two-column" format, but this example does not
appear to me to have that.  If nothing else, it's too short.)

Try this:

    if (((a->op == XNES_step) && (a->size <= XNES_bufsize)) ||
      ((a->op == XNES_fix) && ((a->size + a->leftover) <= XNES_bufsize))) {
	/* code */
    }

(half-unit indent indicating a continuation line)

For a more complex expression I would tend to indent blocks as indicated
by the parenthasization of the expression.

:(Ok, even nroff wouldn't have put the ``)'' at the beginning of a line.  I
:have seen it done by programmers, however.)

Ucky poo.  Blecch.

-- 
	-- David Dyer-Bennet
	...!{rutgers!dayton | amdahl!ems | uunet!rosevax}!umn-cs!ns!ddb
	ddb@Lynx.MN.Org, ...{amdahl,hpda}!bungia!viper!ddb
	Fidonet 1:282/341.0, (612) 721-8967 hst/2400/1200/300

ka@june.cs.washington.edu (Kenneth Almquist) (01/05/89)

> Humans process 2d information extremely well - they are only moderately good
> at parsing long strings.  On the other hand, computers are very good at
> parsing long strings - they are at best only moderately good at processing
> 2d information.

Actually, even computers are pretty good at recognizing indentation.  If
you use Yacc, which expects its input to consist of a series of tokens,
make the lexical analyzer can look at the indentation level and generate
the beginning and ending braces.  I've done this; it takes less than a
page of code to implement.
				Kenneth Almquist

albaugh@dms.UUCP (Mike Albaugh) (01/07/89)

From article <665@brwa.inmos.co.uk>, by conor@inmos.co.uk (Conor O'Neill):
> In article <1046@ns.UUCP> ddb@ns.UUCP (David Dyer-Bennet) writes:
>>I value conservation of vertical space highly, but I don't have the
>>rule about braces you propose.  I tend to agree with the poster who
>>said that braces are necessary only because the compiler isn't smart
>>enough to interpret block structure from the indentation.  Has anybody
>>played with such a compiler, by the way?  Or a checker for C which
  ^^^^^^ I didn't consider it "play" at the time :-)
> 
> The OCCAM language relies entirely on indentation for its block
> structure.  Each level of indentation MUST be 2 spaces.
> (Since OCCAM allows nested functions, etc, any more would push everything
> off the right hand side).
> I find this very useable, especially when combined with a folding editor,
> and it makes it very easy to see the block structure.
> -- 
> Conor O'Neill, Software Group, INMOS Ltd. 

	Alright, that does it ... A hot-head like me should
know better than to get involved with such stuff as "style wars",
but I just _have_ to respond the the growing "braces are compiler
fluff, the _real_ info is in indentation" chorus. I once had the
EXTREME displeasure of porting a small snippet of code for which
the _only_ reference was a published printout, spread over two 
pages, of the algorithm in an "ALGOL like" language with the "minor"
difference that block structure was _solely_ indicated by indentation
(by approximately 2 n-spaces, did I forget to say it was typeset in
a proportional face?).

	Whitespace is one of the very easiest things to subtly
screw up when typesetting, copying, or even (gasp) e-mailing.
Of course, people whose code is never read by other than themselves,
their compiler, or people at their establishment running identical
editors (identically configured) on copies of their code won't have
any problems :-)

	Please, please, please, do not remove the very simple and
cheap redundancy between braces (or begin ... end ) and indentation.

| Mike Albaugh (albaugh@dms.UUCP || {...decwrl!turtlevax!}weitek!dms!albaugh)
| Atari Games Corp (Arcade Games, no relation to the makers of the ST)
| 675 Sycamore Dr. Milpitas, CA 95035		voice: (408)434-1709
| The opinions expressed are my own (Boy, are they ever)

mat@mole-end.UUCP (Mark A Terribile) (01/07/89)

> :Hmm.  Do you mean that you have never written
> :
> :#if ...
> :#  if ...
> :. . .
> :#  else
> 
> Well, I understand dpANS allows the "#" to be the first non-blank character
> on the line, rather than precisely the first, so this could be done in the
> normal obvious way in a compliant compiler.  I believe that that's what I've
> done when I nest conditionals (not too often, obviously).

dpANS is not yet universal.  Besides, I really DO prefer to see the # in the
first column so that I can scan for the conditional compilation grunge right
away--and so that I don't miss some effect of it later on while scanning the
code for something else.
 
> 
>     if (((a->op == XNES_step) && (a->size <= XNES_bufsize)) ||
>       ((a->op == XNES_fix) && ((a->size + a->leftover) <= XNES_bufsize))) {
> 	/* code */
>     }
> For a more complex expression I would tend to indent blocks as indicated
> by the parenthasization of the expression.

Indenting isn't a bad idea.  But is it a good idea to use so many redundant
parens?  When I put parens in, I *mean* them to be there; I *mean* that the
normal, usually correct (ok, except for bitops .vs. relops and equops)
precedence is violated; in their absence, default thinking and default
perception will do just fine.

Do you *really* want to bury the conjuntive/disjuntive operators at the
end or in the middle of the line?  In C they short-circuit, so they have
some flow control responsibility, but in any language their effect is more
a matter of control structure in most instances than it is a matter of
simple value computation.  (My opinion, of course.)  Given that, it makes
sense to keep them up-front and visible.
 
> :(Ok, even nroff wouldn't have put the ``)'' at the beginning of a line.  I
> :have seen it done by programmers, however.)
> 
> Ucky poo.  Blecch.

My feelings exactly--the first few times.  After that, my disgust reaches the
heavens and my exclamations reach the floor above.
-- 

(This man's opinions are his own.)
From mole-end				Mark Terribile

ddb@ns.UUCP (David Dyer-Bennet) (01/12/89)

In article <138@mole-end.UUCP> mat@mole-end.UUCP (Mark A Terribile) writes:
:> 
:>     if (((a->op == XNES_step) && (a->size <= XNES_bufsize)) ||
:>       ((a->op == XNES_fix) && ((a->size + a->leftover) <= XNES_bufsize))) {
:> 	/* code */
:>     }
:> For a more complex expression I would tend to indent blocks as indicated
:> by the parenthasization of the expression.
:
:Indenting isn't a bad idea.  But is it a good idea to use so many redundant
:parens?  When I put parens in, I *mean* them to be there; I *mean* that the
:normal, usually correct (ok, except for bitops .vs. relops and equops)
:precedence is violated; in their absence, default thinking and default
:perception will do just fine.

I'm slightly confused here; I believe the parens above are all copied verbatim
from your example.  Only the whitespace has been changed.

:Do you *really* want to bury the conjuntive/disjuntive operators at the
:end or in the middle of the line? 

Yes, definitely.  For the same reason you want to put them elsewhere:  more
readable.  I dislike leaving a line-end that looks like a statement end
(not being good at parsing ";" mentally), so I try to end a continued
expression line with an operator.  After all, they are infix operators, so
they're going to be infixed most of the time anyway; I've just gotten used
to looking for them there.

 
-- 
	-- David Dyer-Bennet
	...!{rutgers!dayton | amdahl!ems | uunet!rosevax}!umn-cs!ns!ddb
	ddb@Lynx.MN.Org, ...{amdahl,hpda}!bungia!viper!ddb
	Fidonet 1:282/341.0, (612) 721-8967 hst/2400/1200/300

ggs@ulysses.homer.nj.att.com (Griff Smith) (01/13/89)

In article <1066@ns.UUCP>, ddb@ns.UUCP (David Dyer-Bennet) writes:
> In article <138@mole-end.UUCP> mat@mole-end.UUCP (Mark A Terribile) writes:
> :> 
> :Do you *really* want to bury the conjuntive/disjuntive operators at the
> :end or in the middle of the line? 
> 
> Yes, definitely.  For the same reason you want to put them elsewhere:  more
> readable.  I dislike leaving a line-end that looks like a statement end
> (not being good at parsing ";" mentally), so I try to end a continued
> expression line with an operator.

I'm using this as an excuse to suggest a theory: two kinds of people
are arguing, and they have different perceptual strengths.  Mark
Terribile and I seem to be in the `visual' camp.  I `understand'
patterns, but grammar doesn't make much sense to me.  A program is not
`readable' to me; it is a two-dimensional array of meta-symbols that I
organize visually.  The example that I deleted makes best sense to me
when displayed as

if (   mumble
    && mumble
    && mumble
    && mumble )
{
	mumble;
	mumble;
}

I can then extract the if (
			   &&
			   &&
			   &&
		       {

as a single icon and know what it does, at that level of abstraction.
David Dyer-Bennet seems to be a member of the `parsing' school.  These
people like to `read' code instead of `seeing' it.  I won't explain
their perceptions, because I can't empathise with them.  They make life
miserable for me, however.  When they format similar code, it's
something like

if (whatever && something_else &&
	something_on_the_next_line &&
	something_short && something_longer &&
	the_end_of_the_list) {
	mumble;
}

This style maximizes my confusion by forcing me to `find' all the
component markers instead of `seeing' them.  I have lost most of the
visual cues, and I have to go wading through the code with my defective
parser.  I suspect the `parsers' are equally disturbed by having to
discard my superfluous white-space.

I don't have any solutions.  I do wish the two sides would be more
sympathetic to each other's problems.
-- 
Griff Smith	AT&T (Bell Laboratories), Murray Hill
Phone:		1-201-582-7736
UUCP:		{most AT&T sites}!ulysses!ggs
Internet:	ggs@ulysses.att.com

ddb@ns.UUCP (David Dyer-Bennet) (01/14/89)

In article <11091@ulysses.homer.nj.att.com> ggs@ulysses.homer.nj.att.com (Griff Smith) writes:
:I'm using this as an excuse to suggest a theory: two kinds of people
:are arguing, and they have different perceptual strengths.  
:
:David Dyer-Bennet seems to be a member of the `parsing' school.  These
:people like to `read' code instead of `seeing' it.  I won't explain
:their perceptions, because I can't empathise with them.  

I think this analysis is right -- except I think I'm in the visual camp;
I'm the one who was explaining my use of whitespace and placement in
terms of page design, and in terms of finding things visually.

:They make life miserable for me, however.

Er, sorry about that.

:When they format similar code, it's something like
:
:if (whatever && something_else &&
:	something_on_the_next_line &&
:	something_short && something_longer &&
:	the_end_of_the_list) {
:	mumble;
:}

In my case, this would be:

if (whatever && something_else &&
  something on the next line &&
  and_so_forth_on_and_on_until &&
  the_end_of_the_list) {
    the_body;
    of_the;
    compound_statement;
}

And I consider this suboptimally readable.  I don't encounter long continued
booleans in the if that often.  If I did, I might revise my style at least
for those particular statements, because I agree with you that there's some
difficulty separating the conditional from the body in the above.  Do you
have trouble with the simpler case of

if (simple one-line conditional) {
    body_of;
    compound_statement;
}

?  Essentially, I tend to think of "continuation lines" (like the long
conditional in your example) as exception cases, rather than the norm,
so my style handles them less cleanly than what I think of as the common
cases.

:This style maximizes my confusion by forcing me to `find' all the
:component markers instead of `seeing' them.  I have lost most of the
:visual cues, and I have to go wading through the code with my defective
:parser.  I suspect the `parsers' are equally disturbed by having to
:discard my superfluous white-space.

As I format it, the indentation depth provides the visual cue still.
I hope.  I don't parse code well either.  This is easily determined by
presenting me with code formatted in ways contrary to the actual
meaning, and see how long it takes me to find it!

:I don't have any solutions.  I do wish the two sides would be more
:sympathetic to each other's problems.

I'm learning a lot from this dialogue, and I'm really pleased it IS a
dialogue rather than a shouting match.  As you say, we aren't likely to
all come to a common solution, but building understanding of the problem
is valuable.

-- 
	-- David Dyer-Bennet
	...!{rutgers!dayton | amdahl!ems | uunet!rosevax}!umn-cs!ns!ddb
	ddb@Lynx.MN.Org, ...{amdahl,hpda}!bungia!viper!ddb
	Fidonet 1:282/341.0, (612) 721-8967 hst/2400/1200/300