July 17, 2007
Taro Kawagishi wrote:

> 
> 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
July 18, 2007
downs palsat:
> void doWhile(void delegate() pre, lazy bool cond, void delegate() post) {
>   while (true) {
>     pre;
>     if (!cond()) break;
>     post;
>   }
> }

More simply:

void doWhile(void delegate() pre, lazy bool cond, void delegate() post) {
   for (pre; cond; pre) post;
}
July 18, 2007
Taro Kawagishi wrote:
> 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
July 18, 2007
You could also use inline functions eg.

{

  T p;

  T complex_pre()
  {
  }

  T complex_post()
  {
  }

  for( p = complex_pre(); p != null; p = complex_post())
  {
    ..body..
  }

}

Regan
July 18, 2007
downs Wrote:

> Here's a more generic version. This one was tested and shown to work.
> Have fun with it!
>   --downs
> =======================================================================
> import std.stdio, std.string;
> 
> /// Cond is
> void doWhile(P, C, O)(lazy P pre, lazy C cond, lazy O post) {
>    while (true) {
>      static if (is(P==void delegate())) pre()(); else pre();
>      if (!cond()) break;
>      static if (is(O==void delegate())) post()(); else post();
>    }
> }
> 
> // these are the things stupid std.string forces us to do.
> // Tango, with str.length==NOTFOUND, really picked the better approach.
> int find(char[] str, char[] match, int offset) {
>    auto res=std.string.find(str[offset..$], match);
>    if (res==-1) return -1;
>    return res+offset;
> }
> 
> void main() {
>    int pos=0;
>    auto text="This interestingly works.";
>    // Note the way we can switch between using brackets and not using them.
>    doWhile(
>      pos=text.find("i", pos),
>      pos+1, /// equivalent to pos!=-1, except it also demonstrates
>             /// that the conditional can be anything "if" can use.
>      { writefln("Hit at ", pos); ++pos; }
>    );
> }

I am new to D, and this is quite impressive.
I guess we can do a similar thing with function objects in C++.
However my original intention was to do simple things in a simple way.

-Taro

July 18, 2007
Joe Gottman Wrote:

>     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
July 18, 2007
downs wrote:
> Here's a more generic version. This one was tested and shown to work.
> Have fun with it!
>  --downs
> =======================================================================
> import std.stdio, std.string;
> 
> /// Cond is
> void doWhile(P, C, O)(lazy P pre, lazy C cond, lazy O post) {
>   while (true) {
>     static if (is(P==void delegate())) pre()(); else pre();
>     if (!cond()) break;
>     static if (is(O==void delegate())) post()(); else post();
>   }
> }
> 
> // these are the things stupid std.string forces us to do.
> // Tango, with str.length==NOTFOUND, really picked the better approach.
> int find(char[] str, char[] match, int offset) {
>   auto res=std.string.find(str[offset..$], match);
>   if (res==-1) return -1;
>   return res+offset;
> }
> 
> void main() {
>   int pos=0;
>   auto text="This interestingly works.";
>   // Note the way we can switch between using brackets and not using them.
>   doWhile(
>     pos=text.find("i", pos),
>     pos+1, /// equivalent to pos!=-1, except it also demonstrates
>            /// that the conditional can be anything "if" can use.
>     { writefln("Hit at ", pos); ++pos; }
>   );
> }

The usage can also be:

  doWhile(
    pos=text.find("i", pos),
    pos+1,
    (writefln("Hit at ", pos), ++pos )
  );

Only one char less though :P


-- 
Bruno Medeiros - MSc in CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
July 18, 2007
Taro Kawagishi wrote:
> 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.
> 


Argh no! Another foreach_reverse crappy redundant construct. There are at least 3 alternatives in which *IMO* any of them is better than adding a language construct, so votes -= 3 !

Tomas Olsen's:
  while(true) {
    aa...
    if (!cond...) break;
    bb...
  }

Gregor's:
  size_t pos = 0;
  while ((pos = text.find(pattern, pos)) != string::npos) {
    ...
  }

down's:
  doWhile(
    pos = text.find("i", pos),
    pos + 1,
    { writefln("Hit at ", pos); ++pos; }
  );


-- 
Bruno Medeiros - MSc in CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
July 18, 2007
Bruno Medeiros wrote

> Argh no! Another
[...]
> redundant construct.

"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.
>     do {
>         aa;
>     } while (bb) {
>         cc;
>     }
is legal code already, but `cc;' is executed only once after the loop ended.

-manfred
July 18, 2007
Bruno Medeiros Wrote:

> downs wrote:
> > Here's a more generic version. This one was tested and shown to work.
> > Have fun with it!
> >  --downs
> > =======================================================================
> > import std.stdio, std.string;
> > 
> > /// Cond is
> > void doWhile(P, C, O)(lazy P pre, lazy C cond, lazy O post) {
> >   while (true) {
> >     static if (is(P==void delegate())) pre()(); else pre();
> >     if (!cond()) break;
> >     static if (is(O==void delegate())) post()(); else post();
> >   }
> > }
> > 
> > // these are the things stupid std.string forces us to do.
> > // Tango, with str.length==NOTFOUND, really picked the better approach.
> > int find(char[] str, char[] match, int offset) {
> >   auto res=std.string.find(str[offset..$], match);
> >   if (res==-1) return -1;
> >   return res+offset;
> > }
> > 
> > void main() {
> >   int pos=0;
> >   auto text="This interestingly works.";
> >   // Note the way we can switch between using brackets and not using them.
> >   doWhile(
> >     pos=text.find("i", pos),
> >     pos+1, /// equivalent to pos!=-1, except it also demonstrates
> >            /// that the conditional can be anything "if" can use.
> >     { writefln("Hit at ", pos); ++pos; }
> >   );
> > }
> 
> The usage can also be:
> 
>    doWhile(
>      pos=text.find("i", pos),
>      pos+1,
>      (writefln("Hit at ", pos), ++pos )
>    );
> 
> Only one char less though :P
> 
> 
> -- 
> Bruno Medeiros - MSc in CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D

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.