Hello all,
every once in a while I feel uneasy when I find I can't fit my logic into a
do-while or while loop in a concise way.
Here is a C++ example:
void
find_string_occurrences(const string& text, const string& pattern) {
// listing 1
size_t pos = text.find(pattern, 0);
while (pos != string::npos) {
cout << "pattern found at " << pos << "\n";
++pos;
pos = text.find(pattern, pos);
}
}
The way the code is written might look redundant in calling find() twice, but I
think it is reasonable because you can test the loop condition only after you
run function find() but here you can't use a do-while loop which doesn't allow
you to place other statements after the condition statement.
I can write the same logic as in listing 2 and 3 below, but their meanings
would be less clear than listing 1, because the looping condition is in the if
statement together with the break statement in it, and you need to spot the if
statement in the while body to understand it.
// listing 2
size_t pos = 0;
while (true) {
pos = text.find(pattern, pos);
if (pos == string::npos) {
break;
}
cout << "pattern found at " << pos << "\n";
++pos;
}
// listing 3
size_t pos = 0;
do {
pos = text.find(pattern, pos);
if (pos == string::npos) {
break;
}
cout << "pattern found at " << pos << "\n";
++pos;
} while (true);
I think a more natural way to express the logic is to write the code as in
listing 4.
// listing 4
size_t pos = 0;
do {
pos = text.find(pattern, pos);
} while (pos != string::npos) {
cout << "pattern found at " << pos << "\n";
++pos;
}
The meaning of
do {
aa;
} while (bb) {
cc;
}
is
while (true) {
aa;
if (not bb) {
break;
}
cc;
}
and is a natural extension to both of
do {
aa;
} while (bb);
and
while (bb) {
cc;
}
The current while loop and do-while loop will be specialized forms of this
general do-while loop.
The advantage of the new construct will be seen if you have more complex
statements within do and while blocks.
I believe allowing this extended construct will be smooth since it will not
break the existing code.
I think D language would be a great fit to have this feature because the
language seems to be still evolving.

I agree this is the best way to solve this particular problem. How much
different is?
while ((pos = text.find(pattern, pos)) != string::npos) {
...
}
from
do {pos = text.find(pattern, pos)} while (pos != string::npos) {
...
}
do/while may be more neat if you have more then one pre-condition however.

Hello all,
every once in a while I feel uneasy when I find I can't fit my logic into
a do-while or while loop in a concise way. Here is a C++ example:
void
find_string_occurrences(const string& text, const string& pattern) {
// listing 1
size_t pos = text.find(pattern, 0);
while (pos != string::npos) {
cout << "pattern found at " << pos << "\n"; ++pos;
pos = text.find(pattern, pos);
}
}
}
The way the code is written might look redundant in calling find() twice,
but I think it is reasonable because you can test the loop condition only
after you run function find() but here you can't use a do-while loop which
doesn't allow you to place other statements after the condition statement.
I can write the same logic as in listing 2 and 3 below, but their meanings
would be less clear than listing 1, because the looping condition is in
the if statement together with the break statement in it, and you need to
spot the if statement in the while body to understand it.
// listing 2
size_t pos = 0;
while (true) {
pos = text.find(pattern, pos);
if (pos == string::npos) {
break;
}
cout << "pattern found at " << pos << "\n"; ++pos;
}
}
// listing 3
size_t pos = 0;
do {
pos = text.find(pattern, pos);
if (pos == string::npos) {
break;
}
cout << "pattern found at " << pos << "\n"; ++pos;
} while (true);
I think a more natural way to express the logic is to write the code as in
listing 4.
// listing 4
size_t pos = 0;
do {
pos = text.find(pattern, pos);
} while (pos != string::npos) {
cout << "pattern found at " << pos << "\n"; ++pos;
}
}
The meaning of
do {
aa;
} while (bb) {
cc;
}
}
is
while (true) {
aa;
if (not bb) {
break;
}
cc;
}
}
and is a natural extension to both of
do {
aa;
} while (bb);
and
while (bb) {
cc;
}
}
The current while loop and do-while loop will be specialized forms of this
general do-while loop.
The advantage of the new construct will be seen if you have more complex
statements within do and while blocks. I believe allowing this extended
construct will be smooth since it will not break the existing code. I
think D language would be a great fit to have this feature because the
language seems to be still evolving.

I dont see any reason to further complicate the language for this. As you
already pointed out yourself it can be easily accomplished with the
current language features.
Here's mine:
for(;;)
{
aa;
if (!cond) break;
bb;
}
- Tomas

Hello all,
every once in a while I feel uneasy when I find I can't fit my logic into a
do-while or while loop in a concise way.
Here is a C++ example:
void
find_string_occurrences(const string& text, const string& pattern) {
// listing 1
size_t pos = text.find(pattern, 0);
while (pos != string::npos) {
cout << "pattern found at " << pos << "\n";
++pos;
pos = text.find(pattern, pos);
}
}
The way the code is written might look redundant in calling find() twice, but
I think it is reasonable because you can test the loop condition only after you
run function find() but here you can't use a do-while loop which doesn't allow
you to place other statements after the condition statement.
I can write the same logic as in listing 2 and 3 below, but their meanings
would be less clear than listing 1, because the looping condition is in the if
statement together with the break statement in it, and you need to spot the if
statement in the while body to understand it.
// listing 2
size_t pos = 0;
while (true) {
pos = text.find(pattern, pos);
if (pos == string::npos) {
break;
}
cout << "pattern found at " << pos << "\n";
++pos;
}
// listing 3
size_t pos = 0;
do {
pos = text.find(pattern, pos);
if (pos == string::npos) {
break;
}
cout << "pattern found at " << pos << "\n";
++pos;
} while (true);
I think a more natural way to express the logic is to write the code as in
listing 4.
// listing 4
size_t pos = 0;
do {
pos = text.find(pattern, pos);
} while (pos != string::npos) {
cout << "pattern found at " << pos << "\n";
++pos;
}
The meaning of
do {
aa;
} while (bb) {
cc;
}
is
while (true) {
aa;
if (not bb) {
break;
}
cc;
}
and is a natural extension to both of
do {
aa;
} while (bb);
and
while (bb) {
cc;
}
The current while loop and do-while loop will be specialized forms of this
general do-while loop.
The advantage of the new construct will be seen if you have more complex
statements within do and while blocks.
I believe allowing this extended construct will be smooth since it will not
break the existing code.
I think D language would be a great fit to have this feature because the
language seems to be still evolving.

Forth has this construct in the form of a BEGIN ... WHILE ... REPEAT loop. I
don't think I've seen it elsewhere, though. Uses for it come up fairly
frequently in my experience, but as others have mentioned, the for(;;) { aa; if
(cond) break; bb; } idiom isn't too bad.
Walter uses 'goto' more than any other programmer I've ever seen. Search
through
Phobos and the DMD front-end for 'goto', and see how many could be replaced by
your do-while loop. Is it a significant fraction of the total?

While we are at it, why not just this?
goto mid;
begin:
cc;
mid:
aa;
if (bb) goto begin;
Clear concise and simple, plus it is much closer to the actual machine logic,
and so may imrpove performance as much as -1% ;)
BCS Wrote:

While we are at it, why not just this?
goto mid;
begin:
cc;
mid:
aa;
if (bb) goto begin;
Clear concise and simple, plus it is much closer to the actual machine
logic, and so may imrpove performance as much as -1% ;)

While your point is relevant, the actual reason for doing it the way I pointed
out is not performance, but the removal of duplicate source code. I am a
firm believer in the assertion that anytime you have duplication of code[*],
you have a bug waiting to happen.
Except for the goto, my example read reasonably clearly and does a reasonable
job of describing what is intended. The original proposal and the other
examples
(except maybe the if()break; example) are not, IMHO, so clear. If you can
think of a better way to show the intent, I'm interested.
*IIRC the XP folks will agree with me, however I'm only looking at code that
is /exactly/ the same, not just abstractable to the same thing.

The point I was trying to make is that while any thing *can* be done through
tricky code, the do {} while {} is such a common problem that I agree with the
OP that it *should* have a distinct syntactical representation.
Intoducing such a basic syntax element to C/C++ at this stage would be nigh
impossible, but D is young enough to adopt something like this, and something
which simplifies syntax and readability is IMHO worth considering.
BCS Wrote:

Reply to Tristam,

While we are at it, why not just this?
goto mid;
begin:
cc;
mid:
aa;
if (bb) goto begin;
Clear concise and simple, plus it is much closer to the actual machine
logic, and so may imrpove performance as much as -1% ;)

While your point is relevant, the actual reason for doing it the way I pointed
out is not performance, but the removal of duplicate source code. I am a
firm believer in the assertion that anytime you have duplication of code[*],
you have a bug waiting to happen.
Except for the goto, my example read reasonably clearly and does a reasonable
job of describing what is intended. The original proposal and the other
examples
(except maybe the if()break; example) are not, IMHO, so clear. If you can
think of a better way to show the intent, I'm interested.
*IIRC the XP folks will agree with me, however I'm only looking at code that
is /exactly/ the same, not just abstractable to the same thing.

Do we need moderators on this group, or are there just a lot of people around
who have more time than things to do.
Kill this thread, it's a waste of Oxygen.
Steve Teale - No qualifications whatsoever, but been doing it since 1965.

Do we need moderators on this group, or are there just a lot of people around
who have more time than things to do.
Kill this thread, it's a waste of Oxygen.

I don't get it. Are you reading these posts out loud? Anyway don't
worry too much. The oxygen's still there, it's just attached to a
carbon atom. I think I heard there was some way to get rid of that
carbon atom, too.
--bb

The advantage of the new construct will be seen if you have more complex
statements within do and while blocks.
I believe allowing this extended construct will be smooth since it will
not break the existing code.
I think D language would be a great fit to have this feature because the
language seems to be still evolving.

I come across this scenario all the time, and it always strikes me as odd
how common the issue is, yet how the language doesn't really provide a
simple way to structure it. Agreed.

I agree, too.
The goto thingy looks quite readable, but depending on how long your
loop is it might not be in practice. Also it would be the first time
I'd use goto.
The for-thingy as well as the doWhile mixin (which per se is *really*
cool) loose some expressiveness. Imagine all code blocks would be
longer. How long would you need to understand the meaning compared to
the proposed construct?
Also I dont like making assignment-stuff in the condition-part of a
while or for loop. I once tried it with this and if you have some
not-too-short variable/function/method names you can easily get a
while-condition thats about 5 lines long which is a pain in the eye.
Votes++;
// Henning
--
GPG Public Key:
http://keyserver.ganneff.de:11371/pks/lookup?op=get&search=0xDDD6D36D41911851
Fingerprint: 344F 4072 F038 BB9E B35D E6AB DDD6 D36D 4191 1851

I like your proposal very much. This pattern is very often, and your
solution clearly shows the intended behaviour of the code. All the other
"solutions" are more obscure and more unclear.
I also think extending D with this new construct is realy simple.
Votes++.
Taro Kawagishi escribió:

Hello all,
every once in a while I feel uneasy when I find I can't fit my logic into a
do-while or while loop in a concise way.
Here is a C++ example:
void
find_string_occurrences(const string& text, const string& pattern) {
// listing 1
size_t pos = text.find(pattern, 0);
while (pos != string::npos) {
cout << "pattern found at " << pos << "\n";
++pos;
pos = text.find(pattern, pos);
}
}
The way the code is written might look redundant in calling find() twice, but
I think it is reasonable because you can test the loop condition only after you
run function find() but here you can't use a do-while loop which doesn't allow
you to place other statements after the condition statement.
I can write the same logic as in listing 2 and 3 below, but their meanings
would be less clear than listing 1, because the looping condition is in the if
statement together with the break statement in it, and you need to spot the if
statement in the while body to understand it.
// listing 2
size_t pos = 0;
while (true) {
pos = text.find(pattern, pos);
if (pos == string::npos) {
break;
}
cout << "pattern found at " << pos << "\n";
++pos;
}
// listing 3
size_t pos = 0;
do {
pos = text.find(pattern, pos);
if (pos == string::npos) {
break;
}
cout << "pattern found at " << pos << "\n";
++pos;
} while (true);
I think a more natural way to express the logic is to write the code as in
listing 4.
// listing 4
size_t pos = 0;
do {
pos = text.find(pattern, pos);
} while (pos != string::npos) {
cout << "pattern found at " << pos << "\n";
++pos;
}
The meaning of
do {
aa;
} while (bb) {
cc;
}
is
while (true) {
aa;
if (not bb) {
break;
}
cc;
}
and is a natural extension to both of
do {
aa;
} while (bb);
and
while (bb) {
cc;
}
The current while loop and do-while loop will be specialized forms of this
general do-while loop.
The advantage of the new construct will be seen if you have more complex
statements within do and while blocks.
I believe allowing this extended construct will be smooth since it will not
break the existing code.
I think D language would be a great fit to have this feature because the
language seems to be still evolving.

I think a more natural way to express the logic is to write the code as in
listing 4.
// listing 4
size_t pos = 0;
do {
pos = text.find(pattern, pos);
} while (pos != string::npos) {
cout << "pattern found at " << pos << "\n";
++pos;
}
The meaning of
do {
aa;
} while (bb) {
cc;
}
is
while (true) {
aa;
if (not bb) {
break;
}
cc;
}
and is a natural extension to both of
do {
aa;
} while (bb);
and
while (bb) {
cc;
}

This looks very nice. Does this mean that the entire construct is
one scope, so that a variable declared in the aa section is accessible
in the bb and cc sections and a variable declared in the bb section is
accessible in the cc section?
Joe Gottman

This looks very nice. Does this mean that the entire construct is
one scope, so that a variable declared in the aa section is accessible
in the bb and cc sections and a variable declared in the bb section is
accessible in the cc section?
Joe Gottman

Thank you for your comment.
Having one scope for the entire construct can be useful, but I think it has to
have three separate scopes to be consistent with block rule.
Now I realized this could be the biggest inconvenience with this form.
-Taro

Hello all,
every once in a while I feel uneasy when I find I can't fit my logic into a
do-while or while loop in a concise way.
Here is a C++ example:
void
find_string_occurrences(const string& text, const string& pattern) {
// listing 1
size_t pos = text.find(pattern, 0);
while (pos != string::npos) {
cout << "pattern found at " << pos << "\n";
++pos;
pos = text.find(pattern, pos);
}
}
The way the code is written might look redundant in calling find() twice, but
I think it is reasonable because you can test the loop condition only after you
run function find() but here you can't use a do-while loop which doesn't allow
you to place other statements after the condition statement.

[...]

I think a more natural way to express the logic is to write the code as in
listing 4.
// listing 4
size_t pos = 0;
do {
pos = text.find(pattern, pos);
} while (pos != string::npos) {
cout << "pattern found at " << pos << "\n";
++pos;
}
The meaning of
do {
aa;
} while (bb) {
cc;
}
is
while (true) {
aa;
if (not bb) {
break;
}
cc;
}
and is a natural extension to both of
do {
aa;
} while (bb);
and
while (bb) {
cc;
}
The current while loop and do-while loop will be specialized forms of this
general do-while loop.

I agree with you, and I see the need for such a construct.
But this was already discussed some year ago, and Walter didn't like the
idea.
Ciao

Hello all,
every once in a while I feel uneasy when I find I can't fit my logic into a
do-while or while loop in a concise way.
Here is a C++ example:
void
find_string_occurrences(const string& text, const string& pattern) {
// listing 1
size_t pos = text.find(pattern, 0);
while (pos != string::npos) {
cout << "pattern found at " << pos << "\n";
++pos;
pos = text.find(pattern, pos);
}
}
The way the code is written might look redundant in calling find() twice, but
I think it is reasonable because you can test the loop condition only after you
run function find() but here you can't use a do-while loop which doesn't allow
you to place other statements after the condition statement.
I can write the same logic as in listing 2 and 3 below, but their meanings
would be less clear than listing 1, because the looping condition is in the if
statement together with the break statement in it, and you need to spot the if
statement in the while body to understand it.
// listing 2
size_t pos = 0;
while (true) {
pos = text.find(pattern, pos);
if (pos == string::npos) {
break;
}
cout << "pattern found at " << pos << "\n";
++pos;
}
// listing 3
size_t pos = 0;
do {
pos = text.find(pattern, pos);
if (pos == string::npos) {
break;
}
cout << "pattern found at " << pos << "\n";
++pos;
} while (true);
I think a more natural way to express the logic is to write the code as in
listing 4.
// listing 4
size_t pos = 0;
do {
pos = text.find(pattern, pos);
} while (pos != string::npos) {
cout << "pattern found at " << pos << "\n";
++pos;
}
The meaning of
do {
aa;
} while (bb) {
cc;
}
is
while (true) {
aa;
if (not bb) {
break;
}
cc;
}
and is a natural extension to both of
do {
aa;
} while (bb);
and
while (bb) {
cc;
}
The current while loop and do-while loop will be specialized forms of this
general do-while loop.
The advantage of the new construct will be seen if you have more complex
statements within do and while blocks.
I believe allowing this extended construct will be smooth since it will not
break the existing code.
I think D language would be a great fit to have this feature because the
language seems to be still evolving.

"No" confirmed, but its not redundant: it will break existing code.
I use blocks to group statements:
{ // computing this and that
...
}
and in conjunction with a block no statement needs the `;'-
delimiter!!!
I.e.

I can write the same logic as in listing 2 and 3 below, but their meanings
would be less clear than listing 1, because the looping condition is in
the if statement together with the break statement in it, and you need to
spot the if statement in the while body to understand it.

On seeing a while (true), I think it goes without saying that you need to
look for a break or return statement somewhere to find the terminating
condition.
BTW here are two other ways of doing your particular case:
// listing 5
size_t pos = 0;
while ((pos = text.find(pattern, 0)) != string::npos) {
cout << "pattern found at " << pos << "\n";
++pos;
}
// listing 6
for (size_t pos = 0; (pos = text.find(pattern, 0)) != string::npos;
++pos) {
cout << "pattern found at " << pos << "\n";
}
but I realise this is no use in the more general case when you've got more
to do in the portion before the break.

I think a more natural way to express the logic is to write the code as in
listing 4.
// listing 4
size_t pos = 0;
do {
pos = text.find(pattern, pos);
} while (pos != string::npos) {
cout << "pattern found at " << pos << "\n";
++pos;
}

I'm not sure I like this notation. There are always going to be people who
prefer to put curly brackets on a line of their own. And then, given a
snippet of code
...
}
while (cond)
{
...
it'll be necessary to scroll, possibly through several screens of code, just
to find out whether the block above the while is part of the loop as well.
Moreover, I don't know if it's a common pitfall to write
do {
...
}
(with no while clause) intending an infinite loop (or one that must be
broken out of). But should somebody fall into this trap and follow it
immediately with a while loop, it would take on a whole new meaning.

The current while loop and do-while loop will be specialized forms of this
general do-while loop.
The advantage of the new construct will be seen if you have more complex
statements within do and while blocks.
I believe allowing this extended construct will be smooth since it will
not break the existing code.

I'm still not sure it gains anything practically over the if-break method.
Moreover, what if you want multiple terminating conditions at different
points in the loop? You can put any number of breaks in a loop; your idea
OTOH doesn't easily extend to multiple exit points.
(For the record, Beta Basic on the ZX Spectrum had an "EXIT IF" statement,
really the equivalent of if-break though it also looked a bit like your
idea, especially as the automatic indentation would show that particular
statement at the same level as the DO and LOOP. If you like, you _could_
outdent your if-break statements to achieve the same effect....)
Stewart.

loop
{ size_t pos = text.find(pattern, 0);
// declare a new pos on each iteration??
if (pos == string::npos) break;
cout << "pattern found at " << pos << "\n";
// tango is not standard D, but I think I understand
// what you are doing
++pos;
pos = text.find(pattern, pos);
}
I'd prefer the Ada-esque
exit when (pos == string::npos);
but that means introducing new key words (more than just
"loop"). OTOH, I guess there's nothing wrong with having an
un-parameterized "do" instead of loop, as in:
do
{ ... do stuff ...
when(condition) break;
}
in the case the "when" is semantically the same as an if, but
it clarifies what's going on. One could limit it's use to
"only usable within a do loop". But I would prefer the syntax
of either:
exit when (condition);
or
break when (condition);
as I feel that these are clearer.

I'd prefer the Ada-esque
exit when (pos == string::npos);
but that means introducing new key words (more than just "loop"). OTOH, I
guess there's nothing wrong with having an un-parameterized "do" instead
of loop, as in:
do
{ ... do stuff ...
when(condition) break;
}
in the case the "when" is semantically the same as an if, but it clarifies
what's going on. One could limit it's use to "only usable within a do
loop". But I would prefer the syntax of either:
exit when (condition);
or
break when (condition);
as I feel that these are clearer.

I'd say no to a new keyword just for this.
However, a syntax like
break if (condition);
would, in my opinion, be better than
if (condition) break;

I'd prefer the Ada-esque
exit when (pos == string::npos);
but that means introducing new key words (more than just "loop").
OTOH, I guess there's nothing wrong with having an un-parameterized
"do" instead of loop, as in:
do
{ ... do stuff ...
when(condition) break;
}
in the case the "when" is semantically the same as an if, but it
clarifies what's going on. One could limit it's use to "only usable
within a do loop". But I would prefer the syntax of either:
exit when (condition);
or
break when (condition);
as I feel that these are clearer.

I'd say no to a new keyword just for this.
However, a syntax like
break if (condition);
would, in my opinion, be better than
if (condition) break;

I sit back and watch as D slowly evolves into Ruby... ;)
-- Chris Nicholson-Sauls