www.digitalmars.com         C & C++   DMDScript  

D - Awesome D is

reply Andy Walker <Andy_member pathlink.com> writes:
Congratulations.  

First, the site is well laid out and thoughtful.  Very nice.

Second, the language specs are terrific.  If emulation is the highest form of
compliment, then I paid it to you yesterday.  I went to lunch with a friend of
mine and we laid out our needs in a language, that turned out very similar to D
in many ways.

I am not sure what words to use to search for the following topics.  If I am
rehashing an old discusstion, please direct me to it, and accept my apologies
for the noise.

Naming conventions: Do not allow "_" (single underscore) to begin any
identifier.  Instead, require it ("_") to bein every keyword.  If a token begins
with "_", it is either a keyword, or wrong.  This makes using powerful tools
like "grep" much easier.  It  also tends to reduce newbie errors.  There will be
a lot of them with a new language.

Changing control structures.  Use:
{ _if ( true ) a = b; } instead of   if ( true ) a = b; or if ( true ) { a = b ;
}
{ _else c = d; } instead of  else c = d; or else { c = d; }
{ _elseif ( true ) e = f; }
for  _else and _elseif blocks, each must immediately follow their contrasted _if
or _elseif block.
This syntax is unamgiguous to the developers who must read it.  Also, this is
simpler to parse.  These three keywords must be the first token in the block or
they are wrong.

{ _switch ( myInteger ) ... }       instead of     switch ( myinteger )  { ...
}     
{ _case ( myCase ) ... }      instead of    case ( myCase) : {  ... }
{ _case ( myCase, myOtherCase, myLastCase ) ... }  instead of   case
(myCase):case(myOtherCase):case(myLastCase): { ... }
{ _default ... } instead of default: { ... } 
{ _defaultcase ( my Case, myOtherCase ) ... }  instead of
case(myCase):case(myOtherCase):default: {... }
There is no case-to-case fallthrough here, not ever.  I find "case" fallthrough,
controlled with breaks to be wordy and dangerous. My admittedly anecdotal
experience is that almost all of the blocks of code that I see following case
statements are terminated with break statements.  Every time I have seen a
"fallthrough", ie without a break statement, it has been inadequately commented
or documented.  Again, keywords _switch,  _case, _default, and _defaultcase are
first token in the block, or they are wrong.  

{ _do ( int i, i =1 ; i < imax ; i++ ;  a[i] < amax )  ... }  instead of   for (
.... ) , while (....), or do ... while(...);.  
Note the additional post-body predicate test statement inside the parenthesis.
The following are all allowed ( with syntax exactly like C in the use of "," and
";": 
{ _do (  )  ...  }, -- nothing between parenthesis.  This loop runs until it
executes a break.
{ _do ( int i, i = 0  ) ... }, -- initialize.  This loop runs a long time as
well.                 
{ _do ( int i, i = 0; i < imax ) ... }  -- initialize and test.  Still no
autoincrement.
{ _do ( int i, i = 0; i < imax ; i++) ... }  This should look familiar.
{ _do ( int i, i = 0;; i++; i < imax ) ... }  use a post-body predicate instead
of a pre-body predicate.  Didn't you ever want to use the construction:
for ( i = 0;;i++) { ... } while ( a[i] < amax ) ;
The above sytax has that meaning.
In other words, each of the statements inside the parenthesis are optional.  If
following parenthesis statements are not present, the statement terminator, ";",
may be left out as well. 
Here is how to code a while( i < imax ){ ....} .
{ _do (; i< imax ) ... }
Here is how to code a do{ ...} while ( ... );
{ _do ( ;;; a[i] < amax ) ... }
I am not blind to the fact that the do ... while alternative superficially
violates the "no empty statements" rule.

Formatting: add a type's format specification to the general information about
the type.  For new types, use the base type as the default, but also allow it to
be specified.
e.g.  typedef string [ 20 ] knrtext ( %20.20lc );  (meaning: new type "name",
default formatting, use 20 char field, blank padded to 20 characters, left
justified.
Used like this: 
knrtext  HeWo;
HeWo = "Hello World"
_printf( "\n >>>%D<<< \nThis is a sample of default formatting for D \n", HeWo
);
giving this result:
Hello World         <<<



Sorry. I couldn't resist. My apologies to Messrs. Kernigan and Ritchie, and C programmers everywhere. Add a default format for structures as well, so that the following does not produce parseable garbage, but a powerful and easily evaluated output: _debug _printf ( "\n %D\n", dataStruct ); Add format-time loop control, like so: _printf ( "\n %(20 5.2d) ", a(i)(i = 0;i<20;i++;a(i) < amax ) ); /* prints a row of twenty numbers */ This does not look right, somehow, although it gets the point across. As usual for me, compliments, constructive criticisms, and nasty comments will all be warmly received. Andy Walker jawalker stl.quik.com copyright 2002 by J. Andrew Walker
May 25 2002
parent reply "anderson" <anderson firestar.com.au> writes:
I think?? the "_" (underscore) issue has been already discussed and
discarded by Walter himself (using it for a slightly differn't topic).
Apart from looking bad, the needless reduntancy and the extra two handed
typing need for the "_", Walter wanted to make D easy to learn and convert
from c and c++ and using "_" for every keyword works against this.   We
don't put an underscore in front of every noun (although we capital some of
them).

Infact, the "_" almost put me of reading all of your other comments but see
below...

Sorry to be so tough but, many of the changes you suggest make are unnessary
and make it harder for C/C++ programmers transition.


"Andy Walker" <Andy_member pathlink.com> wrote in message
news:acpm3g$2g2q$1 digitaldaemon.com...
 Congratulations.

 First, the site is well laid out and thoughtful.  Very nice.

 Second, the language specs are terrific.  If emulation is the highest form

 compliment, then I paid it to you yesterday.  I went to lunch with a

 mine and we laid out our needs in a language, that turned out very similar

 in many ways.

 I am not sure what words to use to search for the following topics.  If I

 rehashing an old discusstion, please direct me to it, and accept my

 for the noise.

 Naming conventions: Do not allow "_" (single underscore) to begin any
 identifier.  Instead, require it ("_") to bein every keyword.  If a token

 with "_", it is either a keyword, or wrong.  This makes using powerful

 like "grep" much easier.  It  also tends to reduce newbie errors.  There

 a lot of them with a new language.

I would like my "if-else" commands in differen't colours from my "class" keyword in my IDE anyway.
 Changing control structures.  Use:
 { _if ( true ) a = b; } instead of   if ( true ) a = b; or if ( true ) { a

 }
 { _else c = d; } instead of  else c = d; or else { c = d; }
 { _elseif ( true ) e = f; }
 for  _else and _elseif blocks, each must immediately follow their

 or _elseif block.
 This syntax is unamgiguous to the developers who must read it.  Also, this

 simpler to parse.  These three keywords must be the first token in the

 they are wrong.
 { _switch ( myInteger ) ... }       instead of     switch ( myinteger )

 }
 { _case ( myCase ) ... }      instead of    case ( myCase) : {  ... }
 { _case ( myCase, myOtherCase, myLastCase ) ... }  instead of   case
 (myCase):case(myOtherCase):case(myLastCase): { ... }
 { _default ... } instead of default: { ... }
 { _defaultcase ( my Case, myOtherCase ) ... }  instead of
 case(myCase):case(myOtherCase):default: {... }
 There is no case-to-case fallthrough here, not ever.  I find "case"

 controlled with breaks to be wordy and dangerous. My admittedly anecdotal
 experience is that almost all of the blocks of code that I see following

 statements are terminated with break statements.  Every time I have seen a
 "fallthrough", ie without a break statement, it has been inadequately

 or documented.  Again, keywords _switch,  _case, _default, and

 first token in the block, or they are wrong.

That would require even more typing, I doubt the bracket supporters would go for this one. I would like a way to stop case fall though (ie using anothor name other then switch - "switchbreak") , but this does not do it for me.
 { _do ( int i, i =1 ; i < imax ; i++ ;  a[i] < amax )  ... }  instead of

 .... ) , while (....), or do ... while(...);.
 Note the additional post-body predicate test statement inside the

 The following are all allowed ( with syntax exactly like C in the use of

 ";":
 { _do (  )  ...  }, -- nothing between parenthesis.  This loop runs until

 executes a break.
 { _do ( int i, i = 0  ) ... }, -- initialize.  This loop runs a long time

 well.
 { _do ( int i, i = 0; i < imax ) ... }  -- initialize and test.  Still no
 autoincrement.
 { _do ( int i, i = 0; i < imax ; i++) ... }  This should look familiar.
 { _do ( int i, i = 0;; i++; i < imax ) ... }  use a post-body predicate

 of a pre-body predicate.  Didn't you ever want to use the construction:
 for ( i = 0;;i++) { ... } while ( a[i] < amax ) ;
 The above sytax has that meaning.
 In other words, each of the statements inside the parenthesis are

 following parenthesis statements are not present, the statement

 may be left out as well.
 Here is how to code a while( i < imax ){ ....} .
 { _do (; i< imax ) ... }
 Here is how to code a do{ ...} while ( ... );
 { _do ( ;;; a[i] < amax ) ... }
 I am not blind to the fact that the do ... while alternative superficially
 violates the "no empty statements" rule.

I would like the last ";" to be optional in "for" statements and the step incrementation to default to "++" off the variable declared in the first part of the for. ie for (int n; n<total) instead of, for (int n; n<total; n++) I dissagree with the use of it in "do" statments, as you have presented.
 Formatting: add a type's format specification to the general information

 the type.  For new types, use the base type as the default, but also allow

 be specified.
 e.g.  typedef string [ 20 ] knrtext ( %20.20lc );  (meaning: new type

 default formatting, use 20 char field, blank padded to 20 characters, left
 justified.
 Used like this:
 knrtext  HeWo;
 HeWo = "Hello World"
 _printf( "\n >>>%D<<< \nThis is a sample of default formatting for D \n",

 );
 giving this result:
Hello World         <<<



Sorry. I couldn't resist. My apologies to Messrs. Kernigan and Ritchie,

 programmers everywhere.

It's an ok (I'd give a 1%) idea, but there are alternatives, and personally I don't like the look of it. There otherways to do this type of formatting exist already. Why not have that format in the printf instead, infact It's already possible with printf. One advantage of the code above is resuse, but if your a smart C programmer, I'd make little dif to your D program.
 Add a default format for structures as well, so that the following does

 produce parseable garbage, but a powerful and easily evaluated output:
 _debug _printf ( "\n %D\n", dataStruct );

 Add format-time loop control, like so:
 _printf ( "\n %(20 5.2d) ", a(i)(i = 0;i<20;i++;a(i) < amax )   );   /*

 row of twenty numbers */
 This does not look right, somehow, although it gets the point across.

The idea is cool, but syntax is not. More like _printf ( "\n %(20 5.2d) ", for(i = 0;i<20;i++) return a(i) ); I'd like to be able to write function on the fly like java allows. Of couse this reduces code reusablily and I'd only want to uses it for small bits of code. printf ( "\n %d ", int (a) {return for(i = 0;i<20;i++)a++}} ); //Note, would have differn't output from the above code. or printf ( "\n %d ", int get(a) {return for(i = 0;i<20;i++)a++}} );
 As usual for me, compliments, constructive criticisms, and nasty comments

 all be warmly received.

OK
 Andy Walker
 jawalker stl.quik.com
 copyright   2002 by J. Andrew Walker

May 27 2002
parent reply Andy Walker <Andy_member pathlink.com> writes:
In article <acstdh$2jj3$1 digitaldaemon.com>, anderson says...
I think?? the "_" (underscore) issue has been already discussed and
discarded by Walter

Ok. Discussion over as far as I am concerned. <snip>
Sorry to be so tough but, many of the changes you suggest make are unnessary
and make it harder for C/C++ programmers transition.

As you can tell from my previous posts, I have worked with a LOT of languages. These days, the most common background is C, not FORTRAN or BASIC. A terrific idea from a compilation point of view is worthless if the vast majority of programmers will not use the language because of it. BTW, I do not consider your comments "tough" at all. None of them insult my intelligence. You just have a different point of view. I am still, at heart, a FORTRAN programmer, and do not see with the eyes of a native "C" developer. ( Every two months or so I code a for loop like so: for ( i =0, i < 20, i++ ) ... Note the commas, not semicolons. :-P ) <snip>
I would like my  "if-else" commands in differen't colours from my "class"
keyword in my IDE anyway.

I like multi color editors. Very helpful. <snip proposed MAJOR bracket syntax changes >
That would require even more typing, I doubt the bracket supporters would go
for this one.
I would like a way to stop case fall though (ie using anothor name other
then switch - "switchbreak") , but this does not do it for me.

I think I code "C" the way Pavel codes it, with lots of brackets: if ( a == b) { c = f(z); } else { c = f(z+1); } I wholeheartedly agree, not pretty. But at 2:30 AM, even when stupid for lack of sleep, I can match brackets. I also never worry about whether I need to add brackets if I add a line. I find I do not have time to worry about that. Bugs consume me. This is what I get with my alternative: {if ( a==b) c = f(z); } {else c = f(z+1); } Applied to a switch-case construction: {switch ( tokenchar [0] ) {case ( '_' ) processKeyword ( tokenchar ); } {case ( 'a', 'b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z') processIdentifier ( tokenchar ); } {default throw invalidSyntaxFlag; } } ( I am not rehashing Keyword-leading underscores. This was just the first example I could find ) <snip proposed do-loop alternatives >
I would like the last ";" to be optional in "for" statements and the step
incrementation to default to "++" off the variable declared in the first
part of the for.

ie
for (int n; n<total)
instead of,
for (int n; n<total; n++)

I dissagree with the use of it in "do" statments, as you have presented.

Whether "do" or "for" makes no difference to me. To me, the multiple loop types are redundant. Having to find the post-condition "while" at the end of a block makes me lose my train of thought while trying to understand a block of code. I have noticed that it distracts native "C" programmers as well. I am not partial to the implied auto increment. I have coded with the following style, and generally find it makes things very clear for other developers. E.g. processing two arrays, whose indexes are not similar: for ( i = 0, j = 37 ; i < imax ; i++, j += 13 ) { new_a[ i ] = structArray[ j ].old_a ; }
 Formatting: add a type's format specification to the general information

 the type.  For new types, use the base type as the default, but also allow

 be specified.
 e.g.  typedef string [ 20 ] knrtext ( %20.20lc );  (meaning: new type

 default formatting, use 20 char field, blank padded to 20 characters, left
 justified.
 Used like this:
 knrtext  HeWo;
 HeWo = "Hello World"
 _printf( "\n >>>%D<<< \nThis is a sample of default formatting for D \n",

 );
 giving this result:
Hello World         <<<



Sorry. I couldn't resist. My apologies to Messrs. Kernighan and Ritchie,

 programmers everywhere.

It's an ok (I'd give a 1%) idea, but there are alternatives, and personally I don't like the look of it. There otherways to do this type of formatting exist already. Why not have that format in the printf instead, infact It's already possible with printf. One advantage of the code above is resuse, but if your a smart C programmer, I'd make little dif to your D program.

I suppose what I really want is format type and data type syntax checking, with some declaration-time control. In "C", if I change a data type from a two-byte short to a four-byte long, I must manually check every line of code for format changes, including every header. I always miss one or two. I never get a warning, and when I see unexpected output, I always assume I screwed up an algorithm, not the format. I then waste a lot of time proving I did nothing wrong but the format. It drives me to distraction. I am to the point where I am ready to write a whole new language because this is something the computer should handle, not me. Oh. Wait. That's why we are here. I really like the individual cell formatting allowed by spreadsheets. I can rapidly and correctly modify formats to get just the right "look". ( I find the "C++" stream formatting controls look like hieroglyphics. I always have to stop and decode them. Again, I also have watched native "C" developers do the same thing. Every time I look at implementation details, stream formatting brings in a lot of extra executable code. A lot of things about "C++" are major advances, but stream outputs are not one of them. Flames may be directed to my email address, below. )
 Add a default format for structures as well, so that the following does

 produce parseable garbage, but a powerful and easily evaluated output:
 _debug _printf ( "\n %D\n", dataStruct );

 Add format-time loop control, like so:
 _printf ( "\n %(20 5.2d) ", a(i)(i = 0;i<20;i++;a(i) < amax )   );   /*

 row of twenty numbers */
 This does not look right, somehow, although it gets the point across.

The idea is cool, but syntax is not. More like _printf ( "\n %(20 5.2d) ", for(i = 0;i<20;i++) return a(i) );

Now I see my problem from before. More like printf ( "\n %(20. %5.2d)", for(i=0;i<20;i++)return a(i) ); /* this variation will require ")" in format strings to be escaped to be printed */ printf( "\n %(20 %5.2d%)", for(i=0;i<20;i++)return a(i) ); /* this variation does not, but it is really ugly */ My first construction borrowed from PL/1. Is this from Java?
 I'd like to be able to write function on the fly like java allows. Of couse
this reduces code reusablily and I'd only want to uses it for small bits of
code.
printf ( "\n %d ",  int (a) {return for(i = 0;i<20;i++)a++}} ); //Note,
would have differn't output from the above code.

or

printf ( "\n %d ",  int get(a) {return for(i = 0;i<20;i++)a++}} );

Sorry, but I do not see it. How does this reduce reuse? The format string, the data, and the control loop are all tightly interconnected from a logic point of view. As far as I can tell, no matter how you code it, if any one of these things is changed, the whole process will have to be reviewed.
 As usual for me, compliments, constructive criticisms, and nasty comments

 all be warmly received.

OK

Andy Walker jawalker stl.quik.com
May 27 2002
next sibling parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Andy Walker" <Andy_member pathlink.com> wrote in message
news:actfkn$30t$1 digitaldaemon.com...

 I think I code "C" the way Pavel codes it, with lots of brackets:
 if ( a == b)
 {
 c = f(z);
 }
 else
 {
 c = f(z+1);
 }

Er... that's exactly the opposite to what I'd write: if (a == b) c = f(z); else c = f(z + 1); No brackets! =)
May 27 2002
next sibling parent reply "Martin M. Pedersen" <mmp www.moeller-pedersen.dk> writes:
"Pavel Minayev" <evilone omen.ru> wrote in message
news:actg00$3eo$1 digitaldaemon.com...

     if (a == b)
         c = f(z);
     else
         c = f(z + 1);

 No brackets! =)

c = f(z+(a==b)); No if! :-)
May 27 2002
next sibling parent "Pavel Minayev" <evilone omen.ru> writes:
"Martin M. Pedersen" <mmp www.moeller-pedersen.dk> wrote in message
news:acthvu$5b9$1 digitaldaemon.com...

 c = f(z+(a==b));

 No if! :-)

Hmm... never thought of it. But you are definitely right. I'll remember this, a great piece of code indeed. =) ...now if we could also get read of loops...
May 27 2002
prev sibling next sibling parent reply Karl Bochert <kbochert ix.netcom.com> writes:
On Mon, 27 May 2002 17:11:37 +0100, "Martin M. Pedersen"
<mmp www.moeller-pedersen.dk> wrote:
 "Pavel Minayev" <evilone omen.ru> wrote in message
 news:actg00$3eo$1 digitaldaemon.com...
 
     if (a == b)
         c = f(z);
     else
         c = f(z + 1);

 No brackets! =)

c = f(z+(a==b)); No if! :-)

else clause you could write c = f(z+(a==b)*2 + (a==b)*OFFSET); and when the 'z' in the if clause (also) became 'z-1' c = f (z + (a==b)*2 + (a==b)*OFFSET - (a<=b)); What fun! Karl Bochert
May 27 2002
parent "Matthew Wilson" <mwilson nextgengaming.com> writes:
Well said. Down with code-heroes. Up with quality.

"Karl Bochert" <kbochert ix.netcom.com> wrote in message
news:1103_1022519110 bose...
 On Mon, 27 May 2002 17:11:37 +0100, "Martin M. Pedersen"

 "Pavel Minayev" <evilone omen.ru> wrote in message
 news:actg00$3eo$1 digitaldaemon.com...

     if (a == b)
         c = f(z);
     else
         c = f(z + 1);

 No brackets! =)

c = f(z+(a==b)); No if! :-)


 else clause you could write

     c = f(z+(a==b)*2 + (a==b)*OFFSET);

 and when the 'z' in the if clause (also) became 'z-1'

     c = f (z + (a==b)*2 + (a==b)*OFFSET - (a<=b));

 What fun!
 Karl Bochert

May 27 2002
prev sibling next sibling parent reply "Sean L. Palmer" <seanpalmer earthlink.net> writes:
You could almost get rid of if entirely by the use of ?: and creative
multiplication with 0.  The hardware doesn't have if, it has
test-and-branch.  Conditional goto.  Modern processors don't do if
statements so well anyway, they interfere with deep pipelining.  Maybe a new
kind of conditional construct would be handy?

Sean

"Martin M. Pedersen" <mmp www.moeller-pedersen.dk> wrote in message
news:acthvu$5b9$1 digitaldaemon.com...
 "Pavel Minayev" <evilone omen.ru> wrote in message
 news:actg00$3eo$1 digitaldaemon.com...

     if (a == b)
         c = f(z);
     else
         c = f(z + 1);

 No brackets! =)

c = f(z+(a==b)); No if! :-)

May 27 2002
next sibling parent "Martin M. Pedersen" <mmp www.moeller-pedersen.dk> writes:
Hi,


"Sean L. Palmer" <seanpalmer earthlink.net> wrote in message
news:acu1qb$26f6$1 digitaldaemon.com...
 You could almost get rid of if entirely by the use of ?: and creative
 multiplication with 0.

Actually, you can. But the concept of statements makes it hard. In a functional language I designed many years ago, the first couple of years it had no "if"; only "?:". It worked fine because loop constructs and such was operators too, not statements. But, I must admit, the introduction of "if" made the code clearer :-) Regards, Martin M. Pedersen
May 28 2002
prev sibling parent "Stephen Fuld" <s.fuld.pleaseremove att.net> writes:
"Sean L. Palmer" <seanpalmer earthlink.net> wrote in message
news:acu1qb$26f6$1 digitaldaemon.com...
 You could almost get rid of if entirely by the use of ?: and creative
 multiplication with 0.  The hardware doesn't have if, it has
 test-and-branch.  Conditional goto.  Modern processors don't do if
 statements so well anyway, they interfere with deep pipelining.  Maybe a

 kind of conditional construct would be handy?

Don't confuse the higher level language representation from the actual code generated. A good compiler will match the two. Anyway, many modern CPUs have a conditional move instruction that would eliminate the branches in this case. -- - Stephen Fuld e-mail address disguised to prevent spam
 Sean

 "Martin M. Pedersen" <mmp www.moeller-pedersen.dk> wrote in message
 news:acthvu$5b9$1 digitaldaemon.com...
 "Pavel Minayev" <evilone omen.ru> wrote in message
 news:actg00$3eo$1 digitaldaemon.com...

     if (a == b)
         c = f(z);
     else
         c = f(z + 1);

 No brackets! =)

c = f(z+(a==b)); No if! :-)


May 28 2002
prev sibling parent reply "OddesE" <OddesE_XYZ hotmail.com> writes:
"Martin M. Pedersen" <mmp www.moeller-pedersen.dk> wrote in message
news:acthvu$5b9$1 digitaldaemon.com...
 "Pavel Minayev" <evilone omen.ru> wrote in message
 news:actg00$3eo$1 digitaldaemon.com...

     if (a == b)
         c = f(z);
     else
         c = f(z + 1);

 No brackets! =)

c = f(z+(a==b)); No if! :-)

You don't write an if, but the conditional check is there allright. Also, you are making your code dependant on the fact that false==0 and true==1. A dangerous assumption... I think this code is less clear at no gain. Losing the braces is allright, but losing the if! No! :) -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net _________________________________________________ Remove _XYZ from my address when replying by mail
May 29 2002
next sibling parent reply "anderson" <anderson firestar.com.au> writes:
"OddesE" <OddesE_XYZ hotmail.com> wrote in message
news:ad3d84$1eic$1 digitaldaemon.com...
 "Martin M. Pedersen" <mmp www.moeller-pedersen.dk> wrote in message
 news:acthvu$5b9$1 digitaldaemon.com...
 "Pavel Minayev" <evilone omen.ru> wrote in message
 news:actg00$3eo$1 digitaldaemon.com...

     if (a == b)
         c = f(z);
     else
         c = f(z + 1);

 No brackets! =)

c = f(z+(a==b)); No if! :-)

You don't write an if, but the conditional check is there allright. Also, you are making your code dependant on the fact that false==0 and true==1. A dangerous assumption... I think this code is less clear at no gain. Losing the braces is allright, but losing the if! No! :)

Then c = f(z+(a==b)?1:0); But, using Martin's method could be more optinal because I doen't require a branch, which is a slow down on modern CPU's that use read-ahead (because I has to stop the pipeline and reload stuff from the cashe or even the very slow RAM). Although I consider c = f(z+(a==b)) quite a neat one liner. But I agree that things of this nature begin to get criptic for the average programmer and I only use them when performace matters in the optimisation programming cycle.
 --
 Stijn
 OddesE_XYZ hotmail.com
 http://OddesE.cjb.net
 _________________________________________________
 Remove _XYZ from my address when replying by mail

May 30 2002
parent reply Roland <rv ronetech.com> writes:
anderson a écrit :

 "OddesE" <OddesE_XYZ hotmail.com> wrote in message
 news:ad3d84$1eic$1 digitaldaemon.com...
 "Martin M. Pedersen" <mmp www.moeller-pedersen.dk> wrote in message
 news:acthvu$5b9$1 digitaldaemon.com...
 "Pavel Minayev" <evilone omen.ru> wrote in message
 news:actg00$3eo$1 digitaldaemon.com...

     if (a == b)
         c = f(z);
     else
         c = f(z + 1);

 No brackets! =)

c = f(z+(a==b)); No if! :-)

You don't write an if, but the conditional check is there allright. Also, you are making your code dependant on the fact that false==0 and true==1. A dangerous assumption... I think this code is less clear at no gain. Losing the braces is allright, but losing the if! No! :)

Then c = f(z+(a==b)?1:0); But, using Martin's method could be more optinal because I doen't require a branch, which is a slow down on modern CPU's that use read-ahead (because I has to stop the pipeline and reload stuff from the cashe or even the very slow RAM).

The _perfect_ optimizer, may compile same code. it must unassemble something like: mov eax,a cmp eax,b setz al movzx eax,al add eax,z . . witch i'm quite sure is much faster than mov eax,a cmp eax,b mov eax,z jnz not_equal ;<-- arg .. poor microprocessor inc eax not_equal: . . .. because a jump is the worst thing you can do to you dear microprocessor. I have to check this kind of code with DM C++ and make a suggestion of optimisation on C++ thread if necessary. All form like if (a==b) z++; or if (a<b) z++; (here use adc intruction) .. can be optimized the same way. But i should stop brainstorm alone here as i would be not surprised if its already optimized in DM C++
 Although I consider c = f(z+(a==b)) quite a neat one liner.

I agree, if c = f(z+(a==b)) is less readeable than if (a==b) { c = f(z+1); } else { c = f(z); } 100 lines are _more_ readeable than 500 lines. roland
May 30 2002
next sibling parent reply "Christian Schüler" <cschueler gmx.de> writes:
Keep in mind that from Pentium II upwards, there are conditional move
instructions:

    mov    eax, a
    cmp    eax, b
    cmovnz    eax, 0      ; *
    cmovz    eax, 1      ; *
    add    eax, z



 The _perfect_ optimizer, may compile same code.
 it must unassemble something like:

     mov  eax,a
     cmp  eax,b
     setz  al
     movzx  eax,al
     add  eax,z
     .
     .
 witch i'm quite sure is much faster than

     mov  eax,a
     cmp  eax,b
     mov  eax,z
     jnz    not_equal    ;<-- arg .. poor microprocessor
     inc    eax
 not_equal:
     .

May 30 2002
parent Roland <rv ronetech.com> writes:
"Christian Schüler" a écrit :

 Keep in mind that from Pentium II upwards, there are conditional move
 instructions:

     mov    eax, a
     cmp    eax, b
     cmovnz    eax, 0      ; *
     cmovz    eax, 1      ; *
     add    eax, z

Really ! May be i have to change my Intel book: 486 cpu, 1990 .... roland
May 31 2002
prev sibling parent reply "OddesE" <OddesE_XYZ hotmail.com> writes:
"Roland" <rv ronetech.com> wrote in message
news:3CF67636.F550087A ronetech.com...
 Although I consider c = f(z+(a==b)) quite a neat one liner.

I agree, if c = f(z+(a==b)) is less readeable than if (a==b) { c = f(z+1); } else { c = f(z); } 100 lines are _more_ readeable than 500 lines. roland

The dependancy on the if returning 0 for false or 1 for true, then using that boolean value as if it was an integer seems to me to pose a threat. Most languages forbid this kind of construction and I think for good reason. Booleans are false or true. That D uses 0 and 1 to represent them is an implementation issue, albeit a very standard one. I think code should rely on implementation issues as least as possible. And I do think that the long example was much more readable that the short example. If there is a very good reason to use such a construction (performance perhaps), then by all means, use it. Just don't use it just because it looks cool... -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net _________________________________________________ Remove _XYZ from my address when replying by mail
Jun 01 2002
next sibling parent reply "Pavel Minayev" <evilone omen.ru> writes:
"OddesE" <OddesE_XYZ hotmail.com> wrote in message
news:adbqbv$1qo9$1 digitaldaemon.com...

 Booleans are false or true. That D uses 0 and 1
 to represent them is an implementation issue,
 albeit a very standard one. I think code should
 rely on implementation issues as least as possible.

It's not an implementation issue. The "bit" data type is not a boolean - it's a 1-bit unsigned integer, which can hold either 0 or 1. For convenience, true and false are mapped to equal 1 and 0, respectively... I think it was supposed to work this way. =)
Jun 02 2002
parent reply "anderson" <anderson firestar.com.au> writes:
And of coarse in most ASM set (true) has always been represented by 1 and
unset (false) has always been represented by 0.  So it makes sense to use
those values in the bit type flags.

"Pavel Minayev" <evilone omen.ru> wrote in message
news:adcg9a$2j0d$1 digitaldaemon.com...
 "OddesE" <OddesE_XYZ hotmail.com> wrote in message
 news:adbqbv$1qo9$1 digitaldaemon.com...

 Booleans are false or true. That D uses 0 and 1
 to represent them is an implementation issue,
 albeit a very standard one. I think code should
 rely on implementation issues as least as possible.

It's not an implementation issue. The "bit" data type is not a boolean - it's a 1-bit unsigned integer, which can hold either 0 or 1. For convenience, true and false are mapped to equal 1 and 0, respectively... I think it was supposed to work this way. =)

Jun 02 2002
parent "OddesE" <OddesE_XYZ hotmail.com> writes:
"anderson" <anderson firestar.com.au> wrote in message
news:adcjol$2mjf$1 digitaldaemon.com...
 And of coarse in most ASM set (true) has always been represented by 1 and
 unset (false) has always been represented by 0.  So it makes sense to use
 those values in the bit type flags.

Ofcourse, just not as the expression/return value for an if... I know that if (2) printf ('Hello World.'); Will print Hello World, and that int i = 3 + (2 < 5); Will assign 4 to i, but in my humble opinion it is not something that is obviously clear, or desirable for that matter. It is one of those features of C often critisised. It has some advantages, but also opens the door for errors. most style guides and programming books advise you to avoid such constructions. -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net _________________________________________________ Remove _XYZ from my address when replying by mail
Jun 03 2002
prev sibling parent "Sean L. Palmer" <seanpalmer earthlink.net> writes:
"OddesE" <OddesE_XYZ hotmail.com> wrote in message
news:adbqbv$1qo9$1 digitaldaemon.com...

 The dependancy on the if returning 0 for false or
 1 for true, then using that boolean value as if it
 was an integer seems to me to pose a threat.
 Most languages forbid this kind of construction
 and I think for good reason.
 Booleans are false or true. That D uses 0 and 1
 to represent them is an implementation issue,
 albeit a very standard one. I think code should
 rely on implementation issues as least as possible.

 And I do think that the long example was much more
 readable that the short example. If there is a
 very good reason to use such a construction
 (performance perhaps), then by all means, use it.
 Just don't use it just because it looks cool...

Performance is usually an issue one should keep in mind. I agree, the long one is more readable. Sometimes that's a larger concern than performance. For games programming, performance is critical. Then again, portability is important also. I think C's mistake is that it was a very general representation of the hardware *at the time C was invented*. Todays machines are a different style of beast altogether, and a different style of programming is necessary to achieve top performance on today's CPU's. For this we need access to modern day constructs such as parallel execution, which occurs in forms ranging from SIMD to multithreading. D addresses many of those issues. I believe the D spec already specifies the conversion from bool to bit; it's implicit in the conversion from int to bit. Because on the D webpage it says: Integer Promotions The following types are implicitly converted to int: bit byte ubyte short ushort enum Typedefs are converted to their underlying type. But it doesn't specify anything about how to convert actual values of one type into values of the other type. Personally I'd prefer that it *did* do so; then I'd be absolved of much of the tedium of dealing with porting issues. It turns that problem into a language implementation problem rather than a machine incompatibility problem. I *like* languages that make guarantees about how things work in a machine. If my program says convert int to float and on this machine, there is no float unit, I want the compiler to emulate it in software so that my program still works. Luckily for me, machines don't change *all* that much and so, from year to year, there are certain standards that prosper. IEEE floating point format, standard two's complement signed integers, and byte sizes of 8 and int sizes (in bytes) which are a power of 2. But we can't rely on that. However the language can specify conversion behavior for bit to int and int to bit. However it would have to know whether bit was a signed or unsigned quantity to do it properly. Both are useful if you think about it: bit select; int a,b; int which = cast(int)select^a + cast(int)!select^b; // in fact the casts are unnecessary they're only there to make explicit what's going on. This is neat because a bit then expands to fill the available space. For this to work however you need signed bits which expand to int -1 or (for 32 bit ints) 0xffffffff. If bit 1 == int 1, it won't work at all (but multiply would). I tend to think of bools as signed bits but that's just me. I've seen one programming problem which would be neatly solved by a form of integer than replicated downwards, and in fact I believe this is how modern graphics coprocessors work; the integers represent values to a specified resolution. Essentially fixed point but the decimal point may be anywhere; depending on the registers and type of cpu it may be 0.0 .. 1.0 or 0.0 .. 255.0 or -128.9999999 to +127.0 or 0.0 to 0.25 or whatever. Conversion then is based on where the implicit decimal points are. The neat thing is the fractional part replicates infinitely into a larger fraction. For instance let's treat a color RGB as unsigned fraction from 0.0 to 1.0. 0.0 == 0 and 1.0 == 255. Then if we have a color let's say light gray or 0xaaaaaa. Let's also say we want to paint it onto a bitmap that only has 4 bits of color for each R,G, and B. The resulting pixel is 0xaaa. So to convert each 4 bit pixel back to the original, we need something that converts to the original value 0xaaaaaa. 0xaa / ((2^8)-1) = 0xa / ((2^4)-1) 0xaa / 255 = 0xa / 15 0xaa = 0xa * 255 / 15 Anyway I believe basic types should be present which are guaranteed to behave in certain ways by the language spec, but that a machine should also expose any other custom types it possesses which may be governed by other rules of behavior. Fixed point is a very common pattern in day-to-day programming, and it would be nice if it had some language support. Emulation of fixed point is something that can be automated by the compiler; it's a very simple algorithm to construct fixed point math on any integer register set. The compiler would know where the decimal point was for each type and could convert automatically very easily. The multiplication and division are very solved problems even if the machine doesn't have larger intermediate registers. Hell I remember when the CPU's didn't even have hardware multiply. Do you think machines will come out that don't have hardware integer multiply? Well they also aren't going to make machines that don't have larger intermediate registers for multiplication/division. And even if they don't, many applications for fixed point only need the add and subtract to be fast and don't care about the final division being fast. I can see it being used in a variety of fields; computer graphics would want binary fixed point and finance would want modulo 100 fixed point. For instance if I want to convert the color white to portion of a dollar (so I can use my GeForce 3 to calculate my spreadsheet ;) it would need 0xff / ((2&8)-1) = 99 / (100-1). It'd be nice if the compiler could manage the conversions for us. I recently ported a game where fixed point math was used for the graphics calculations (it was a PS1 game) and it sucked. Anything that automates this stuff with clean syntax and some hope of portability would be great. This may tie into specifying ranges for scalar types. Range and precision are closely connected. int24.8 somefraction = 4.0f; int16.16 otherfraction = -0x1ad.ee3; int32 intermediate = somefraction * otherfraction * 100; extended temp = somefraction * otherfraction + 0.5f; int32 result = temp * 100; int0.4 percent = result / intermediate; Yes I doubt the above syntax would work in practice. But the concept is neat. For it to work, it relies on the compiler's ability to convert safely from one type to another; Right now though we live in an era of computing where we get no guarantees about converting between integral types let alone fixed point types. I think the language should attempt to give the programmers some safety net within which the world is guaranteed to work a certain way. If D someday ends up on some radically different hardware where this no longer works and emulation would be too slow, the software is likely to be out of date anyway and there are likely to be bigger porting issues to deal with. The language can and should morph to the new architectures; if it can't, someone will invent a new language and we'll repeat this process again. Sean
Jun 02 2002
prev sibling parent reply "Martin M. Pedersen" <mmp www.moeller-pedersen.dk> writes:
Hi,

"OddesE" <OddesE_XYZ hotmail.com> wrote in message
news:ad3d84$1eic$1 digitaldaemon.com...
 c = f(z+(a==b));
 No if! :-)


 Losing the braces is allright, but losing
 the if! No!  :)

I agree. It was partly ment as a joke, and partly to illustrate that code isn't better, just because it is shorter. Same goes for braces. Regarding performance, I don't think that the code above is any better than code using ?: or if/else - given the right compiler. Regards, Martin M. Pedersen
May 30 2002
parent "OddesE" <OddesE_XYZ hotmail.com> writes:
"Martin M. Pedersen" <mmp www.moeller-pedersen.dk> wrote in message
news:ad5jg6$1sgk$1 digitaldaemon.com...
 Hi,

 "OddesE" <OddesE_XYZ hotmail.com> wrote in message
 news:ad3d84$1eic$1 digitaldaemon.com...
 c = f(z+(a==b));
 No if! :-)


 Losing the braces is allright, but losing
 the if! No!  :)

I agree. It was partly ment as a joke, and partly to illustrate that code isn't better, just because it is shorter. Same goes for braces. Regarding performance, I don't think that the code above is any better than code

 ?: or if/else - given the right compiler.

 Regards,
 Martin M. Pedersen

Hah, you fooled me :P Sorry if I reacted to hard... :) -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net _________________________________________________ Remove _XYZ from my address when replying by mail
May 30 2002
prev sibling parent reply Andy Walker <Andy_member pathlink.com> writes:
My apologies.  I was browsing the code in DedicateD and assumed it was your.

Andy

In article <actg00$3eo$1 digitaldaemon.com>, Pavel Minayev says...
"Andy Walker" <Andy_member pathlink.com> wrote in message
news:actfkn$30t$1 digitaldaemon.com...

 I think I code "C" the way Pavel codes it, with lots of brackets:
 if ( a == b)
 {
 c = f(z);
 }
 else
 {
 c = f(z+1);
 }

Er... that's exactly the opposite to what I'd write: if (a == b) c = f(z); else c = f(z + 1); No brackets! =)

May 27 2002
parent "Pavel Minayev" <evilone omen.ru> writes:
"Andy Walker" <Andy_member pathlink.com> wrote in message
news:acu44e$2fs5$1 digitaldaemon.com...

 My apologies.  I was browsing the code in DedicateD and assumed it was

You've probably seen the SDL samples. No, these aren't mine, I've just translated them to D, and I didn't perform any "beautification".
May 27 2002
prev sibling next sibling parent "anderson" <anderson firestar.com.au> writes:
"Andy Walker" <Andy_member pathlink.com> wrote in message
news:actfkn$30t$1 digitaldaemon.com...
 In article <acstdh$2jj3$1 digitaldaemon.com>, anderson says...
I think?? the "_" (underscore) issue has been already discussed and
discarded by Walter


 Whether "do" or "for" makes no difference to me.  To me, the multiple loop

 are redundant.  Having to find the post-condition "while" at the end of a

 makes me lose my train of thought while trying to understand a block of

 have noticed that it distracts native "C" programmers as well.

 I am not partial to the implied auto increment.  I have coded with the

 style, and generally find it makes things very clear for other developers.

 E.g. processing two arrays, whose indexes are not similar:

 for (     i  = 0,         j = 37    ;
 i < imax                  ;
 i++,            j += 13  )
 {
 new_a[ i ] = structArray[ j ].old_a ;
 }

fair enough
 Now I see my problem from before.  More like

 printf ( "\n %(20. %5.2d)", for(i=0;i<20;i++)return a(i)    );
 /* this variation will require ")" in format strings to be escaped to be

 */

 printf(  "\n %(20 %5.2d%)", for(i=0;i<20;i++)return a(i)    );
 /* this variation does not, but it is really ugly   */

 My first construction borrowed from PL/1.  Is this from Java?

No it was an idea, probably got for formating wrong, and the code above is not quite right (it needs work). Also isn't d used for integers. The formating
 I'd like to be able to write function on the fly like java allows. Of


this reduces code reusablily and I'd only want to uses it for small bits


code.
printf ( "\n %d ",  int (a) {return for(i = 0;i<20;i++)a++}} ); //Note,
would have differn't output from the above code.

or

printf ( "\n %d ",  int get(a) {return for(i = 0;i<20;i++)a++}} );

Sorry, but I do not see it. How does this reduce reuse? The format

 data, and the control loop are all tightly interconnected from a logic

 view.  As far as I can tell, no matter how you code it, if any one of

 things is changed, the whole process will have to be reviewed.

Sorry I mean't, reduce reuse as a bad think (I don't think I'm termming it properly). In otherwords, it doesn't premote resuable functions. If you have a function created inside another function, you can't use it outside the function, so it's probably no a good Idea. I found it most useful for event driven programming.
 Andy Walker
 jawalker stl.quik.com

May 27 2002
prev sibling next sibling parent "Walter" <walter digitalmars.com> writes:
"Andy Walker" <Andy_member pathlink.com> wrote in message
news:actfkn$30t$1 digitaldaemon.com...
  I am still, at heart, a
 FORTRAN programmer, and do not see with the eyes of a native "C"

 Every two months or so I code a for loop like so:  for ( i =0, i < 20,

 Note the commas, not semicolons. :-P   )

I come from a FORTRAN background myself. I've been doing C for so long now, though, I doubt I could ever write a working FORTRAN program again. A couple months ago I tried to help some people port some FORTRAN code I wrote 25 years ago, but it just escapes me. But I still use i,j,k,l,m as integer variables <g>.
May 27 2002
prev sibling parent reply "Sean L. Palmer" <seanpalmer earthlink.net> writes:
"Andy Walker" <Andy_member pathlink.com> wrote in message
news:actfkn$30t$1 digitaldaemon.com...
 Whether "do" or "for" makes no difference to me.  To me, the multiple loop

 are redundant.  Having to find the post-condition "while" at the end of a

 makes me lose my train of thought while trying to understand a block of

 have noticed that it distracts native "C" programmers as well.

I wouldn't mind integrating the various loop structures together somehow... a loop is a loop is a loop. Oftentimes I find myself wanting a for loop that does the test at the end of the block. In fact oftentimes I find myself coding if (a) do { a = input(); } while (a); just to make it explicitly clear to the compiler what kind of code I want it to generate. (the above is a while loop) It'd be nice if the compiler always translated while(a) { foo(); } to: goto test; loopbody: foo(); test: if (a) goto loopbody; In fact my usual loop construct is a count-down for loop like so: for (int i = container.size(); --i>=0; ) f(container[i]); Notice that container.size() only gets executed once, even if the compiler is stupid or you're in a debug build. Sean
 I am not partial to the implied auto increment.  I have coded with the

 style, and generally find it makes things very clear for other developers.

 E.g. processing two arrays, whose indexes are not similar:

 for (     i  = 0,         j = 37    ;
 i < imax                  ;
 i++,            j += 13  )
 {
 new_a[ i ] = structArray[ j ].old_a ;
 }

 Formatting: add a type's format specification to the general



about
 the type.  For new types, use the base type as the default, but also



it to
 be specified.
 e.g.  typedef string [ 20 ] knrtext ( %20.20lc );  (meaning: new type

 default formatting, use 20 char field, blank padded to 20 characters,



 justified.
 Used like this:
 knrtext  HeWo;
 HeWo = "Hello World"
 _printf( "\n >>>%D<<< \nThis is a sample of default formatting for D



HeWo
 );
 giving this result:
Hello World         <<<



Sorry. I couldn't resist. My apologies to Messrs. Kernighan and



and C
 programmers everywhere.

It's an ok (I'd give a 1%) idea, but there are alternatives, and


I don't like the look of it.  There otherways to do this type of


exist already. Why not have that format in the printf instead, infact


already possible with printf. One advantage of the code above is resuse,


if your a smart C programmer, I'd make little dif to your D program.

I suppose what I really want is format type and data type syntax checking,

 some declaration-time control.  In "C", if I change a data type from a

 short to a four-byte long, I must manually check every line of code for

 changes, including every header.  I always miss one or two.  I never get a
 warning, and when I see unexpected output, I always assume I screwed up an
 algorithm, not the format.  I then waste a lot of time proving I did

 wrong but the format.  It drives me to distraction.  I am to the point

 am ready to write a whole new language because this is something the

 should handle, not me.

 Oh.  Wait.  That's why we are here.

 I really like the individual cell formatting allowed by spreadsheets.  I

 rapidly and correctly modify formats to get just the right "look".

 ( I find the "C++" stream formatting controls look like hieroglyphics.  I

 have to stop and decode them.  Again, I also have watched native "C"

 do the same thing.  Every time I look at implementation details, stream
 formatting brings in a lot of extra executable code.  A lot of things

 "C++" are major advances, but stream outputs are not one of them.  Flames

 directed to my email address, below. )

 Add a default format for structures as well, so that the following does

 produce parseable garbage, but a powerful and easily evaluated output:
 _debug _printf ( "\n %D\n", dataStruct );

 Add format-time loop control, like so:
 _printf ( "\n %(20 5.2d) ", a(i)(i = 0;i<20;i++;a(i) < amax )   );   /*

 row of twenty numbers */
 This does not look right, somehow, although it gets the point across.

The idea is cool, but syntax is not. More like _printf ( "\n %(20 5.2d) ", for(i = 0;i<20;i++) return a(i) );

Now I see my problem from before. More like printf ( "\n %(20. %5.2d)", for(i=0;i<20;i++)return a(i) ); /* this variation will require ")" in format strings to be escaped to be

 */

 printf(  "\n %(20 %5.2d%)", for(i=0;i<20;i++)return a(i)    );
 /* this variation does not, but it is really ugly   */

 My first construction borrowed from PL/1.  Is this from Java?

 I'd like to be able to write function on the fly like java allows. Of


this reduces code reusablily and I'd only want to uses it for small bits


code.
printf ( "\n %d ",  int (a) {return for(i = 0;i<20;i++)a++}} ); //Note,
would have differn't output from the above code.

or

printf ( "\n %d ",  int get(a) {return for(i = 0;i<20;i++)a++}} );

Sorry, but I do not see it. How does this reduce reuse? The format

 data, and the control loop are all tightly interconnected from a logic

 view.  As far as I can tell, no matter how you code it, if any one of

 things is changed, the whole process will have to be reviewed.

 As usual for me, compliments, constructive criticisms, and nasty



will
 all be warmly received.

OK

Andy Walker jawalker stl.quik.com

May 27 2002
next sibling parent reply "Carlos" <carlos8294 msn.com> writes:
 I wouldn't mind integrating the various loop structures together

 a loop is a loop is a loop.  Oftentimes I find myself wanting a for loop

Maybe it'd be nice to have something like VB. If you want to do this (from C): while (cond) { ... }; you do this (in VB): do while cond ... loop Or like this: do until not ( cond ) ... loop (parenthesis aren't mandatory) Or if you want to do this: do { ... } while (cond); You do this: do ... loop while cond Or do ... loop until not (cond) The do..loop construction in VB is really powerful. You can even write: do ... loop To make an infinite loop. Maybe that (or something like that) could be a solution to have loops integrated under a same instruction.
May 27 2002
parent reply "anderson" <anderson firestar.com.au> writes:
"Carlos" <carlos8294 msn.com> wrote in message
news:acubka$2vqp$1 digitaldaemon.com...
 I wouldn't mind integrating the various loop structures together

 a loop is a loop is a loop.  Oftentimes I find myself wanting a for loop

Maybe it'd be nice to have something like VB. If you want to do this (from C): while (cond) { ... }; you do this (in VB): do while cond ... loop

or while cond ... wend
 Or like this:

 do until not ( cond )
 ...
 loop

 (parenthesis aren't mandatory) Or if you want to do this:

 do {
 ...
 } while (cond);

 You do this:

 do
 ...
 loop while cond

 Or

 do
 ...
 loop until not (cond)

 The do..loop construction in VB is really powerful. You can even write:

 do
 ...
 loop

 To make an infinite loop. Maybe that (or something like that) could be a
 solution to have loops integrated under a same instruction.

May 27 2002
parent "Carlos" <carlos8294 msn.com> writes:
 do while cond
 ...
 loop

or while cond ... wend

May 27 2002
prev sibling parent reply "OddesE" <OddesE_XYZ hotmail.com> writes:
"Sean L. Palmer" <seanpalmer earthlink.net> wrote in message
news:acu1lt$26dh$1 digitaldaemon.com...

 In fact my usual loop construct is a count-down for loop like so:

 for (int i = container.size(); --i>=0; )
   f(container[i]);

 Notice that container.size() only gets executed once, even if the compiler
 is stupid or you're in a debug build.

 Sean


I was discussing this with a friend lately and we both came to the conclusion that looping backwards is safer and easier (no need for a temporary count variable to force optimization) in the general case. You can remove elements from the container and it wouldn't matter. Is there a reason you never see this kind of loop used in examples in books? Is there a performance loss from looping backwards? -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net _________________________________________________ Remove _XYZ from my address when replying by mail
May 29 2002
next sibling parent C.R.Chafer <blackmarlin nospam.asean-mail.com> writes:
OddesE wrote:

 Is there a reason you never see this kind of loop used
 in examples in books? Is there a performance loss from
 looping backwards?

I do not know why this is not used in books, but it is probably because when teaching how to use a for loop construct this would add an extra layer of complexity. As for performance loss, on the x86 processor this is not true - and in some cases performance may actually be improved due to optimising away the compare. C 2002/5/30
May 30 2002
prev sibling next sibling parent "anderson" <anderson firestar.com.au> writes:
"OddesE" <OddesE_XYZ hotmail.com> wrote in message
news:ad3dn1$1f4v$1 digitaldaemon.com...
 "Sean L. Palmer" <seanpalmer earthlink.net> wrote in message
 news:acu1lt$26dh$1 digitaldaemon.com...

 In fact my usual loop construct is a count-down for loop like so:

 for (int i = container.size(); --i>=0; )
   f(container[i]);


 I was discussing this with a friend lately and we both
 came to the conclusion that looping backwards is safer
 and easier (no need for a temporary count variable to
 force optimization) in the general case. You can remove
 elements from the container and it wouldn't matter.

<SNIP> I never though of that, interesting.
 --
 Stijn
 OddesE_XYZ hotmail.com
 http://OddesE.cjb.net
 _________________________________________________
 Remove _XYZ from my address when replying by mail

May 30 2002
prev sibling parent reply "Sean L. Palmer" <seanpalmer earthlink.net> writes:
The only drawback to this type of loop that I know of is that the count
variable *must* be signed or iterating all the way to zero doesn't work.

Oh, and it iterates backwards.  Sometimes the algorithm depends on going
forward.

Sean

"OddesE" <OddesE_XYZ hotmail.com> wrote in message
news:ad3dn1$1f4v$1 digitaldaemon.com...
 "Sean L. Palmer" <seanpalmer earthlink.net> wrote in message
 news:acu1lt$26dh$1 digitaldaemon.com...
 In fact my usual loop construct is a count-down for loop like so:

 for (int i = container.size(); --i>=0; )
   f(container[i]);

 Notice that container.size() only gets executed once, even if the


 is stupid or you're in a debug build.

I was discussing this with a friend lately and we both came to the conclusion that looping backwards is safer and easier (no need for a temporary count variable to force optimization) in the general case. You can remove elements from the container and it wouldn't matter. Is there a reason you never see this kind of loop used in examples in books? Is there a performance loss from looping backwards?

May 30 2002
parent reply "OddesE" <OddesE_XYZ hotmail.com> writes:
"Sean L. Palmer" <seanpalmer earthlink.net> wrote in message
news:ad5omn$141s$1 digitaldaemon.com...
 The only drawback to this type of loop that I know of is that the count
 variable *must* be signed or iterating all the way to zero doesn't work.

 Oh, and it iterates backwards.  Sometimes the algorithm depends on going
 forward.

 Sean

Ah yes, if you try to iterate to zero with an unsigned value, then it can never become smaller than zero, so you never leave the loop! I hadn't thought of that one... -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net _________________________________________________ Remove _XYZ from my address when replying by mail
Jun 01 2002
parent reply "Juan Carlos Arevalo Baeza" <jcab roningames.com> writes:
"OddesE" <OddesE_XYZ hotmail.com> wrote in message
news:adbqht$1r2f$1 digitaldaemon.com...

 "Sean L. Palmer" <seanpalmer earthlink.net> wrote in message
 news:ad5omn$141s$1 digitaldaemon.com...
 The only drawback to this type of loop that I know of is that the count
 variable *must* be signed or iterating all the way to zero doesn't work.

Ah yes, if you try to iterate to zero with an unsigned value, then it can never become smaller than zero, so you never leave the loop! I hadn't thought of that one...

for (unsigned int i = container.size(); i>0; ) { --i; f(container[i]); } Ah! And the braces are your friends. Never be so lazy that you miss to use them. Salutaciones, JCAB
Jun 07 2002
next sibling parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Juan Carlos Arevalo Baeza" <jcab roningames.com> wrote in message
news:adqs8d$102t$1 digitaldaemon.com...

 for (unsigned int i = container.size(); i>0; ) {
    --i;
    f(container[i]);
 }

    Ah! And the braces are your friends. Never be so lazy that you miss to
 use them.

Hm? for (uint i = container.length; i > 0; i--) f(container[i]);
Jun 07 2002
parent reply "Juan Carlos Arevalo Baeza" <jcab roningames.com> writes:
"Pavel Minayev" <evilone omen.ru> wrote in message
news:adr122$15hu$1 digitaldaemon.com...

 "Juan Carlos Arevalo Baeza" <jcab roningames.com> wrote in message
 news:adqs8d$102t$1 digitaldaemon.com...

 for (unsigned int i = container.size(); i>0; ) {
    --i;
    f(container[i]);
 }

for (uint i = container.length; i > 0; i--) f(container[i]);

Nope. That's equivalent to: for (uint i = container.length; i > 0;) { f(container[i]); --i; } Unless D differs from C++ in this regard, of course.
    Ah! And the braces are your friends. Never be so lazy that you miss


 use them.

Hm?

I mean always, ALWAYS, use the braces. You're less likely to have (or cause) problems that way. It's a recommendation. It's good advice.
Jun 07 2002
parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Juan Carlos Arevalo Baeza" <jcab roningames.com> wrote in message
news:adr3d2$180b$1 digitaldaemon.com...

     for (uint i = container.length; i > 0; i--)
         f(container[i]);

Nope. That's equivalent to: for (uint i = container.length; i > 0;) { f(container[i]); --i; }

Okay, then: for (uint i = container.length; i-- > 0;) f(container[i]);
    I mean always, ALWAYS, use the braces. You're less likely to have (or
 cause) problems that way. It's a recommendation. It's good advice.

I've already stated my position on this subject a lot of times. =)
Jun 07 2002
parent "Juan Carlos Arevalo Baeza" <jcab roningames.com> writes:
"Pavel Minayev" <evilone omen.ru> wrote in message
news:adrdev$1hs8$1 digitaldaemon.com...

 Okay, then:

      for (uint i = container.length; i-- > 0;)
          f(container[i]);

That works. But...
    I mean always, ALWAYS, use the braces. You're less likely to have (or
 cause) problems that way. It's a recommendation. It's good advice.

I've already stated my position on this subject a lot of times. =)

He he... What would we do without religion... :-P Salutaciones, JCAB
Jun 07 2002
prev sibling parent reply "Sean L. Palmer" <seanpalmer earthlink.net> writes:
"Juan Carlos Arevalo Baeza" <jcab roningames.com> wrote in message
news:adqs8d$102t$1 digitaldaemon.com...
 "OddesE" <OddesE_XYZ hotmail.com> wrote in message
 news:adbqht$1r2f$1 digitaldaemon.com...

 "Sean L. Palmer" <seanpalmer earthlink.net> wrote in message
 news:ad5omn$141s$1 digitaldaemon.com...
 The only drawback to this type of loop that I know of is that the



 variable *must* be signed or iterating all the way to zero doesn't



 Ah yes, if you try to iterate to zero with
 an unsigned value, then it can never become
 smaller than zero, so you never leave the
 loop! I hadn't thought of that one...

for (unsigned int i = container.size(); i>0; ) { --i; f(container[i]); }

Has anyone thought of doing this:? for (unsigned int i = container.size(); i-- > 0; ) { f(container[i]); } btw does i-->0 parse as i -- > 0 or i - -> 0? This still assumes that array-style indexing is equivalent in performance to pointer access or iteration. In most architectures it's better performance-wise to use a pointer. On Intel you can get away with either depending on the size of your struct and how good the compiler is at optimizing (some compilers could rewrite the above to:) for (container::operator[](int).resulttype* i = &container[i], e = &container(0); i-- > e; ) { f(*i); } If it could see it well enough that it knew operator -- and [] were doing trivial array indexing. I'm pretty sure the good modern compilers do this. Ah! And the braces are your friends. Never be so lazy that you miss to
 use them.

Right. Although braces are too error-prone; I'd like something more like a IDE that treated { as "indent the text following this as if it were part of an indented block which starts here and ends at the next }" an automatic pretty printer if you will. It could even parse D on the fly and generate {} when appropriate. The editor's "indent" command could put indentation in (surround the selected text with "{" / "}"). I just don't want to have to type them. That'd be just way too much work, no? ;) So I wonder how your favorite compiler decides to compile each one, and do timings, see which one generates faster code? count-up loop or count-down loop; pre or postincrement or pointer or index... that's what, 8 permutations to try? Try with different struct sizes too; try with 1, 3, 4, 17, 32, 124 Who can write the fastest array comparison? Sean
 Salutaciones,
                          JCAB

Jun 07 2002
parent "Pavel Minayev" <evilone omen.ru> writes:
"Sean L. Palmer" <seanpalmer earthlink.net> wrote in message
news:adrvio$23mn$1 digitaldaemon.com...

 Has anyone thought of doing this:?

 for (unsigned int i = container.size(); i-- > 0; )
 {
    f(container[i]);
 }

I did already! =) See the post above.
 btw does i-->0 parse as i -- > 0 or i - -> 0?

Applying the rule of the first token, it'll be "i -- > 0". Since the second minus CAN serve as a continuation of the first, it WILL. Just like in any lexer I've seen (and written) so far.
 Right.  Although braces are too error-prone;  I'd like something more like

 IDE that treated { as "indent the text following this as if it were part

 an indented block which starts here and ends at the next }" an automatic
 pretty printer if you will.  It could even parse D on the fly and generate
 {} when appropriate.  The editor's "indent" command could put indentation

 (surround the selected text with "{" / "}").

 I just don't want to have to type them.  That'd be just way too much work,
 no?   ;)

I guess we need a D code beautifier. Sounds like a worthy project.
Jun 07 2002