Stylistic note on loops

A

Anthony Tolle

I'm doing some text parsing and I'd appreciate some input on code styles
for loops.
[snip]

If you care about internationalization and code points outside the
Basic Multilingual Plane:

int i = 0;
final int length = s.length();
while (i < length) {
final int codepoint = s.codePointAt(i);
if (!Character.isLetter(codepoint)) {
break;
}
i += Character.charCount(codepoint);
}
if (i >= length) {
// ALL CHARACTERS WERE LETTERS, OR EMPTY STRING
}

If you are really paranoid, you could also check for valid surrogate
pairs, or pre-screen the string for them.
 
R

Robert Klemme

Except that significant whitespace is usually a notable feature of
pseudocode!

Is it? Hm... Never thought of it that way.
And of course the sigils. I believe this is ruby:

@count = 99

What purpose does the @ serve?

It denotes an instance variable of the object the code is executed
within (i.e. which "self" points to). "count" in contrast is a local
variable (or a method call) or a method parameter. Constants are
identified by a leading uppercase letter.

There's an online version of the first edition of "Programming Ruby":
http://www.ruby-doc.org/docs/ProgrammingRuby/

Beware there are some subtle changes between version 1.8 described in
the document and the current 1.9. But most descriptions are still valid.

If you are looking for more introductory material there's also plenty
around.

Kind regards

robert
 
T

Thomas G. Marshall

One possible alternative is:

    while (*p++ = *q++) {
        /* nothing */
    }

Another is:

    while (*p++ = *q++) {
        continue;
    }

I know you weren't specifically suggesting these per se, but I might
argue that both of those are a form of over-engineering that I don't
think there's a term for. Over verbosity? While they certainly seem
safer overall, it somehow seems just a little more than is necessary
for even the exhausted engineer at 3am hopped on caffeine <--
(tiredness & caffeine-addled are my standard metrics for defensive
coding).
 
K

Keith Thompson

Thomas G. Marshall said:
I know you weren't specifically suggesting these per se, but I might
argue that both of those are a form of over-engineering that I don't
think there's a term for. Over verbosity? While they certainly seem
safer overall, it somehow seems just a little more than is necessary
for even the exhausted engineer at 3am hopped on caffeine <--
(tiredness & caffeine-addled are my standard metrics for defensive
coding).

I wasn't specifically suggesting them, but now I will: I specifically
suggest them. I don't find either form overly verbose.

In this particular case, I'd say that a loop with an empty body is
sufficiently unusual that there should be *some* explicit way of
indicating it; otherwise it's easily mistaken for a typo.

For example, suppose you see this:

while (*p++ = *q++);
do_something;

Clearly the code is either incorrect or poorly formatted -- but which?
Maybe the author's tab stop settings just don't match yours.

YMMV, and apparently it does. I'm aware that my personal taste in
C coding style is more verbose than the average.
 
T

Thomas G. Marshall

I wasn't specifically suggesting them, but now I will: I specifically
suggest them.  I don't find either form overly verbose.

In this particular case, I'd say that a loop with an empty body is
sufficiently unusual that there should be *some* explicit way of
indicating it; otherwise it's easily mistaken for a typo.

For example, suppose you see this:

    while (*p++ = *q++);
        do_something;

[...snip...]

Well that gets to the heart of what I was talking about. The
"suppose". I don't really go much out of my way any longer to solve
problems I don't think I've ever seen. Maybe overly verbose is less
what I was getting at and more something similar to "not worth my
thought".

Maybe another example of what I consider over protection that I
occasionally see trumpeted are using things like the following:

if (0 == something) ....

to prevent the accidental

if (something = 0) ....

compiler accepted typo. I suppose I am not doing this for an
aditional reason in that it perhaps goofs up the way we sound out
things we read, but even if it didn't---I wouldn't worry about it. In
fact, it seems more worth it to me to spend time telling others to not
spend time worrying about it. LOL.
 
S

Stefan Ram

Keith Thompson said:
I'd say that a loop with an empty body is sufficiently
unusual that there should be *some* explicit way of
indicating it; otherwise it's easily mistaken for a typo.

I just spotted a typo above! You wrote »it;«, surely you
wanted to write »it,«. (Ok, you could have intentionally
written »it;« in theory, that would not be actually wrong
but very unusual [»The semicolon has been gradually
disappearing, not only from newspapers, but from books« -
slate] and should have *some* explicit way of indicating it
added.)

Ok, if you would be a great literature writer, then you
might use such semicolons without further indications, just
as for example the renowned programmer Donald E. Knuth used
semicolons as loop bodies in a program he wrote two months
ago without further indication:

»for (p=buf;*p==' ';p++);
(...)
for (p=buf+1;*p==' ';p++);
for (q=p+1;*q!='\n';q++);
(...)
for (k=0,cyc[cycptr]=w;w.x!=cyc[k].x || w.y!=cyc[k].y;k++);«

http://www-cs-faculty.stanford.edu/~uno/programs/dragon-calc.w

Ok, this is a short program, and he used this »);« four
times therein, but otherwise this is VERY RARE. We normal
mortal programmers should NEVER take code written by very
good programmers as a model for our own code. It would
be much too smart, no one would understand it anymore,
our coworkers would would think we were arrogant, and,
worst of all, our managers would not be able to read it!

But can we be absolutely certain that Donald E. Knuth did
not make a typo above? Why don't you write a letter to him,
explaining that his loop already ends with this semicolon
(possibly, he will be surprised to learn this!), and suggest
that he double-checks whether this was really intended and
then add some explicit indication to it?
For example, suppose you see this:
while (*p++ = *q++);
do_something;

Yes, but here to clue that hints us of the possibility of an
error is the indentation, not the semicolon. It would be the
same problem with braces:

while (*p++ = *q++){}
do_something;

Or,

while (*p++ = *q++){ /* intentionally empty */ }
do_something;
 
S

Stefan Ram

(e-mail address removed)-berlin.de (Stefan Ram) quotes:
for (p=buf+1;*p==' ';p++);
for (q=p+1;*q!='\n';q++);

These two loops were written by Knuth in sequence as quoted.
He seems to want to skip spaces, and then newline characters.
This reminds me of code I quoted before:

|while( isspace( *++c )); while( isnum( *++c ));

which was then dismissed by Eric as

|wrong, unless the "certain circumstances" happen to include
|foreknowledge that the string is exactly of the given form,

Well, Donald E. Knuth is known to always be grateful for
reports of possible errors in his code.
 
K

Keith Thompson

I just spotted a typo above! You wrote »it;«, surely you
wanted to write »it,«. (Ok, you could have intentionally
[SNIP]

If you'd care to make the point without being quite so sarcastic,
I'd be glad to discuss it with you. And argument from authority
doesn't particularly impress me. Certainly Knuth is a better
programmer and computer scientist than I am; that doesn't mean I
don't, or shouldn't, prefer my own coding style to his.
Yes, but here to clue that hints us of the possibility of an
error is the indentation, not the semicolon. It would be the
same problem with braces:

while (*p++ = *q++){}
do_something;

Or,

while (*p++ = *q++){ /* intentionally empty */ }
do_something;

No, it wouldn't. The problem with the original version:

while (*p++ = *q++);
do_something;

is that it's hard to be sure whether the author messed up the
indentation on the second line:

while (*p++ = *q++);
do_something;

or added an unintended semicolon:

while (*p++ = *q++)
do_something;

Braces would make it obvious which was intended.
 
T

Thomas G. Marshall

  I just spotted a typo above! You wrote »it;«, surely you
  wanted to write »it,«. (Ok, you could have intentionally

[SNIP]

If you'd care to make the point without being quite so sarcastic,
I'd be glad to discuss it with you.  And argument from authority
doesn't particularly impress me.

....nor I (regarding Knuth), though his intent with the ";" thing may
have just been humor. In any case, the more I reflect on this I dig
up vague recollections of

while (..........) {}

as well as the s/{}$/; :)
 
N

Nick

Keith Thompson said:
No, it wouldn't. The problem with the original version:

while (*p++ = *q++);
do_something;

is that it's hard to be sure whether the author messed up the
indentation on the second line:

while (*p++ = *q++);
do_something;

or added an unintended semicolon:

while (*p++ = *q++)
do_something;

Braces would make it obvious which was intended.

I agree entirely with this, but have always found putting the semicolon
on a line by itself - something that you never see in any other
circumstances (he says recklessly) - plenty of indication that there is
an empty loop body and that it's intentional. If you always use braces
for every loop and if body - and many do - then braces would be more
consistent. I tend not to (and know it means that I have to add them
sometimes, and that sometimes I leave them in when I reduce bodies to
one line, when to be utterly consistent I ought to remove them) and so
use the singleton semicolon.
 
N

Nick Keighley

Ian Collins ha scritto:










and what if sometime in the future you need to meat up a bit the body of
the loop?

then you add the curly brackets. This is a variant of the YAGNI
principle.

I use this layout standard and it doesn't cause me grief.

how about
while (*p++ = *q++)
continue;
 
N

Nick Keighley

Of course I have to throw in Ruby here.  Very clean syntax, clean OO
implementation and no significant whitespace.  I often find that Ruby
code looks like pseudo code - but it actually can be executed.  :)

when faced with the choice of learning python or ruby I chose python.
ruby looked a bit strange. Having skimmed the tutorial you mention it
looks a lot less strange! But if you write pseudo code like this then
heaven help your collegues!


ARGF.each { |line| print line if line =~ /Ruby/ }
 
I

Ian Collins

then you add the curly brackets. This is a variant of the YAGNI
principle.

I use this layout standard and it doesn't cause me grief.

how about
while (*p++ = *q++)
continue;

But would still make people used to the idiomatic case wonder why the
continue?
 
N

Nick Keighley

But would still make people used to the idiomatic case wonder why the
continue?

well I don't find the usual idiom clear enough

while (*p++ = *q++);

I want a minimum of two lines. I usually use

while (*p++ = *q++)
;

though in reality I hardly ever do a simple copy like this- I use
strcpy()
 
N

Nick

Nick Keighley said:
well I don't find the usual idiom clear enough

I'm not sure that is the usual idiom, actually.
while (*p++ = *q++);

I want a minimum of two lines. I usually use

while (*p++ = *q++)
;

I do too.
though in reality I hardly ever do a simple copy like this- I use
strcpy()

No, but there are reasons to do it:

/var/www/canal$ grep -B1 '^ *; *$' source/*.c
source/bigops.c- while(*tag && *tag==' ') // skip leading spaces
source/bigops.c: ;
 
L

Lew

I find that it looks like pseudo-programming. Sure, it can be executed, but
it's the writer who should be.

Nick said:
when faced with the choice of learning python or ruby I chose python.
ruby looked a bit strange. Having skimmed the tutorial you mention it
looks a lot less strange! But if you write pseudo code like this then
heaven help your collegues!

ARGF.each { |line| print line if line =~ /Ruby/ }

Let's just bring back APL, why don't we?
 
J

James Dow Allen

Have you ever actually seen a case where the semicolon was
actuallly unintended?

I've seen 2 or 3 instances in FSF's gnu libc of the formula

#define FOO(xxx) \
do { floogy(xxx); } while (0);

where the trailing ";" was obviously a typo. (It defeats
the whole purpose of this special do while (0) macro idea.)
I assume the coder "knew what he was doing", but added
the ";' almost by reflex, and never noticed thereafter!

(The "bug" may not have ill effect since the whole idea of the
macro is to allow embedding FOO(xxx) in, e.g. an if/else
or some such, and the code, we might infer, never did that.)

James
 
T

Thomas G. Marshall

....[snip]...
Python has been called 'executable pseudocode'. If written cleanly, it is
highly readable, even to those who don't know it.

Seems to me I heard this of COBOL once. ;)

If written badly, of course, it's as bad as the cleanest bits of perl.

I have argued against perl endlessly because of this. It seems to be
something that its designer was so very proud of, at least in the
beginning. $| is gross.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,772
Messages
2,569,588
Members
45,100
Latest member
MelodeeFaj
Top