Computer Old Farts Forum
 help / color / mirror / Atom feed
* [COFF] [TUHS] What would early alternatives to C have been?
@ 2025-03-12  2:22 Douglas McIlroy
  2025-03-12 18:52 ` [COFF] " Dan Cross
  0 siblings, 1 reply; 2+ messages in thread
From: Douglas McIlroy @ 2025-03-12  2:22 UTC (permalink / raw)
  To: stuff, Larry McVoy, Arnold Robbins; +Cc: COFF

Beating a nearly dead horse, I'm shipping this to COFF instead of TUHS
to which it responds.

>  I find
>
>       if (a == b && c == d)
>
> perfectly reasonable, but
>
>       if ((a == b) && (c == d))
>
> to be just silly.

Amusing. IT's odd that no one has mentioned the use of spaces for
grouping.  When the operands of == are simple, I prefer to vary the
spacingy spacing. It's less intrusive than extra parentheses and just
as clear.

        if(a==b && c==d) or
        if( a==b && c==d )

K&R usually flank every infix operator with spaces, unlike classical
mathematical usage, where spacing reflects operator precedence. I
usually write a*b + c*d, not a * b + c * d, which wantonly flattens
the parse tree. Here's an example from K&R, where uniform spacing
hampers intelligibility.

        for (i = 0; s[i] >= '0' && s[i] <= '9'; ++i)
                n = 10 * n + (s[i] - '0');

The "extra" parens in the second line admirably show the intent of the
subtraction. Other groupings are not so well indicated. I would write
it like this:

        for(i=0; s[i]>='0' && s[i]<='9'; ++i)
                 n = 10*n + (s[i]-'0');

(I'll admit that the juxtaposition ]>= is less than perspicuous.)

Long identifiers constitute a level of grouping that takes precedence
even over multiplication. So I may flank long identifiers with spaces.
I suppose then + in a sum of  products might deserve double spaces.
That's probably a bridge too far, but double spaces after the
semicolons in the "for" statement above seem justifiable

K&R aren't absolutely rigid about spacing. In the following oddly
mixed specimen, the first of three operands in a conjunction is spaced
tightly, but the third is not; I guess they feel about != the way I do
about long identifiers.

        i<lim-1 && (c = getchar()) != '\n' && c != EOF

The middle conjunct is a challenge. I'd probably squeeze out the
spaces. But I might instead try to hold it together with outer parens.

Doug

^ permalink raw reply	[flat|nested] 2+ messages in thread

* [COFF] Re: [TUHS] What would early alternatives to C have been?
  2025-03-12  2:22 [COFF] [TUHS] What would early alternatives to C have been? Douglas McIlroy
@ 2025-03-12 18:52 ` Dan Cross
  0 siblings, 0 replies; 2+ messages in thread
From: Dan Cross @ 2025-03-12 18:52 UTC (permalink / raw)
  To: Douglas McIlroy; +Cc: stuff, Arnold Robbins, COFF

On Tue, Mar 11, 2025 at 10:22 PM Douglas McIlroy
<douglas.mcilroy@dartmouth.edu> wrote:
> Beating a nearly dead horse, I'm shipping this to COFF instead of TUHS
> to which it responds.
>
> >  I find
> >
> >       if (a == b && c == d)
> >
> > perfectly reasonable, but
> >
> >       if ((a == b) && (c == d))
> >
> > to be just silly.
>
> Amusing. IT's odd that no one has mentioned the use of spaces for
> grouping.  When the operands of == are simple, I prefer to vary the
> spacingy spacing. It's less intrusive than extra parentheses and just
> as clear.
>
>         if(a==b && c==d) or
>         if( a==b && c==d )

I definitely agree that judicious use of spacing can aid
comprehension, though it can only be a hint to the programmer, since
it's not semantically meaningful to the compiler. I would fear
something like this, given a, b, and c bool:

    if (b||c && a)  /* ?if (b or c) and a? */

Surely experience and good taste can find a happy medium here.

> K&R usually flank every infix operator with spaces, unlike classical
> mathematical usage, where spacing reflects operator precedence. I
> usually write a*b + c*d, not a * b + c * d, which wantonly flattens
> the parse tree. Here's an example from K&R, where uniform spacing
> hampers intelligibility.
>
>         for (i = 0; s[i] >= '0' && s[i] <= '9'; ++i)
>                 n = 10 * n + (s[i] - '0');
>
> The "extra" parens in the second line admirably show the intent of the
> subtraction. Other groupings are not so well indicated. I would write
> it like this:
>
>         for(i=0; s[i]>='0' && s[i]<='9'; ++i)
>                  n = 10*n + (s[i]-'0');
>
> (I'll admit that the juxtaposition ]>= is less than perspicuous.)

I personally like this elements of this style, but I have grown fond this:

    for (i = 0; '0' <= s[i] && s[i] <= '9'; ++i)
        n = 10*n + (s[i] - '0');

Which makes the range comparison obvious and mimics what I'd expect to
see in a written formula using standard mathematical notation. Here,
factors are clustered together without space, while terms are
separated by spaces; again closer to the usual conventions for typeset
mathematical formulae.

> Long identifiers constitute a level of grouping that takes precedence
> even over multiplication. So I may flank long identifiers with spaces.
> I suppose then + in a sum of  products might deserve double spaces.
> That's probably a bridge too far, but double spaces after the
> semicolons in the "for" statement above seem justifiable
>
> K&R aren't absolutely rigid about spacing. In the following oddly
> mixed specimen, the first of three operands in a conjunction is spaced
> tightly, but the third is not; I guess they feel about != the way I do
> about long identifiers.
>
>         i<lim-1 && (c = getchar()) != '\n' && c != EOF
>
> The middle conjunct is a challenge. I'd probably squeeze out the
> spaces. But I might instead try to hold it together with outer parens.

Here, I think a single expression is trying to do too much. Assuming
this extracted from a loop, one might write this as:

    while ((c = getchar()) != EOF) {
        if (i < lim - 1 && c != '\n')
            /* do something with c and increment i */
    }

Though I'm a fan of Dijkstra's guarded statements, which can be
simulated in C via conditions and break:

    while ((c = getchar()) != EOF) {
        if (c == '\n' || i >= lim)
            break;
        /* Do something with c and i. */
    }

The question of indentation levels and characters for them comes up
frequently. Here, I use 4 space indent because gmail won't accept tab
literals, which I'm most accustomed to from Unix source code. Nowadays
it doesn't matter that much, but I imagine in the early PDP-11 days it
did, from a space saving perspective on small disks.

I was always struck by how John Lions's commentary formatted the
source code so that the first indentation level was 4 spaces, and
subsequent levels 8 spaces (I think. My copy isn't to hand just now).
I thought that was visually rather appealing.

        - Dan C.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2025-03-12 18:53 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-03-12  2:22 [COFF] [TUHS] What would early alternatives to C have been? Douglas McIlroy
2025-03-12 18:52 ` [COFF] " Dan Cross

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).