www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - suggested improvements to D

reply Warren D Smith <wds math.temple.edu> writes:
Here are some suggested improvements for D.

a <--> b;
swaps a and b, same as making a tempvar t and then  t=a; a=b; b=t;
As was pointed out by Robert W. Floyd ages ago, in his Turing award
lecture (but nobody listened) this comes up so
often it is worth having special syntax for it.


labeled break and continue statements:
that was a fine idea to eliminate a lot of gotos.
HOWEVER, the most common way in which gotos happen that's not covered by D's
break and continue is this:

for(some loop condition){
  if(something){ goto A; }
}
fallthru_code;
A:
break_out_code;

is there a nice way to handle these without gotos?   One possibility
is to add a "default"
block at ends of loops:
for(some loop condition){
  if(something){ break; }
}default{
  fallthru_code;
}
break_out_code;


popcount and first1:
Often one represents a set by means of an array of booleans, or
equivalently by the bits of a machine word.
Now, the cray used to have a wonderful "popcount" machine-instruction
 a = popcount(b);
which would cause the number of 1-bits in the uint b, to be placed in
the integer a.
E.g. popcount(21)=3.
Also, some machines had a "first1" instruction which would cause, e.g,
  c=0;
  printf("here are the locations of the 1bits in b: ");
  for(a = first1(b); b!=0; b >>= a){
     c += a;
     printf("%d,", c);
  }
  printf("\n");
to work as a way to loop thru the elements of the set.

This was all very fine.  It led to TREMENDOUS speedup and
simplification of the right kinds of programs.
BUT, later hardware got rid of the instruction and languages
did not have these as features.  Vicious circle:
  Hardware designers:  no language has popcount and first1, so we see no
reason to support it in hardware.
  Language designers: hardware does not support these, so why should
our language?
Break the cycle - put these in D!   This'll speed up chess programs by
a factor of 2.

[Aside:
Another excellent hardware instruction that as far as I know was never
implemented is
the "dovetail" and "undovetail" instructions
which place the even-indexed bits of a word into a halfword, and the
odd-index ones
into another (undovetail) and dovetail is the reverse.]


Undenying access to arithmetic:
hardware goes to a great amount of trouble to provide add-with-carry,
multiply-two-singlewords-to-get-a-doubleword,
long-division-with-quotient&remainder
(if a is a doubleword divide a by b to get quotient q and remainder r,
all singlewords), etc. to us.
Another good thing available in a lot of hardware is shift-with-carry,
and circular shift with and without carry.
Why the hell does the language then tell the user to go screw
themselves - we intend to deny
you access to that power??!!!
Hello?  This makes it very painful or
difficult or slow
to build a bignum package.  It is just gratuitously asinine.  If D
delivered this it'd (a) be veyr easy, (b) instantly attract a lot of converts
and you could build a portable bignum code that ran about 4
times faster.

Warren D. Smith
http://RangeVoting.org  <-- add your endorsement (by clicking
"endorse" as 1st step)
and
math.temple.edu/~wds/homepage/works.html
Jan 08 2007
next sibling parent reply Kirk McDonald <kirklin.mcdonald gmail.com> writes:
Warren D Smith wrote:
 Here are some suggested improvements for D.

'swap' can easily be done with a function template: void swap(T) (inout T a, inout T b) { T t = a; a = b; b = t; } The second example seems like a perfectly reasonable place to just use goto. The other suggestions seem like precisely the kind of thing we have an inline assembler for. -- Kirk McDonald Pyd: Wrapping Python with D http://pyd.dsource.org
Jan 08 2007
parent Leandro Lucarella <llucarella integratech.com.ar> writes:
Kirk McDonald escribió:
 Warren D Smith wrote:
 Here are some suggested improvements for D.

'swap' can easily be done with a function template: void swap(T) (inout T a, inout T b) { T t = a; a = b; b = t; }

This should be in phobos, if it's not allready. -- Leandro Lucarella Integratech S.A. 4571-5252
Jan 09 2007
prev sibling next sibling parent BCS <ao pathlink.com> writes:
Reply to Warren,

 popcount and first1:

available using intrinsics
 to work as a way to loop thru the elements of the set.
 This was all very fine.  It led to TREMENDOUS speedup and
 simplification of the right kinds of programs.
 BUT, later hardware got rid of the instruction and languages
 did not have these as features.  Vicious circle:
 Hardware designers:  no language has popcount and first1, so we see
 no
 reason to support it in hardware.
 Language designers: hardware does not support these, so why should
 our language?
 Break the cycle - put these in D!   This'll speed up chess programs by
 a factor of 2.
 

IIRC thay can be emulated with a bit not and an add or subtract (I forget exactly how)
 Undenying access to arithmetic:
 hardware goes to a great amount of trouble to provide add-with-carry,
 multiply-two-singlewords-to-get-a-doubleword,
 long-division-with-quotient&remainder
 (if a is a doubleword divide a by b to get quotient q and remainder r,
 all singlewords), etc. to us.

 to build a bignum package.  It is just gratuitously asinine.  If D
 delivered this it'd (a) be veyr easy, (b) instantly attract a lot of
 converts
 and you could build a portable bignum code that ran about 4
 times faster.
 Warren D. Smith

take a look at this: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.announce&article_id=6217 Not fantastically clean, but language support for these without using inline ASM would be "difficult".
Jan 08 2007
prev sibling next sibling parent Knud Soerensen <4tuu4k002 sneakemail.com> writes:
On Tue, 09 Jan 2007 01:40:25 +0000, Warren D Smith wrote:

 Here are some suggested improvements for D.

 
 popcount and first1:
 Often one represents a set by means of an array of booleans, or
 equivalently by the bits of a machine word.
 Now, the cray used to have a wonderful "popcount" machine-instruction
  a = popcount(b);
 which would cause the number of 1-bits in the uint b, to be placed in
 the integer a.
 E.g. popcount(21)=3.
 Also, some machines had a "first1" instruction which would cause, e.g,
   c=0;
   printf("here are the locations of the 1bits in b: ");
   for(a = first1(b); b!=0; b >>= a){
      c += a;
      printf("%d,", c);
   }
   printf("\n");
 to work as a way to loop thru the elements of the set.
 
 This was all very fine.  It led to TREMENDOUS speedup and
 simplification of the right kinds of programs.
 BUT, later hardware got rid of the instruction and languages
 did not have these as features.  Vicious circle:
   Hardware designers:  no language has popcount and first1, so we see no
 reason to support it in hardware.
   Language designers: hardware does not support these, so why should
 our language?
 Break the cycle - put these in D!   This'll speed up chess programs by
 a factor of 2.
 

Well if we generalise the concept of array slicing to index generator functions. Then if onebits(b) returned the index for 1-bits in b then you example could be written: foreach(c in onebits(b)) { printf("%d,", c); } and popcount(b) as onebits(b).length expanding the generator functions to more dimensions would be very helpful in numerical calculations. Ex. the generator function symmetric(3) generated the 3 dimensional symmetric permutations e.g.: (0,1,2) (2,0,1) (1,2,0) and antisymmetic(3): (0,2,1) (2,1,0) (1,0,2) then using the vectorzation syntax from http://all-technology.com/eigenpolls/dwishlist/index.php?it=10 the determinant of the 3x3 matrix "a" can be written by. det=sum([i in symmetric(3)](a[0,i[0]]*a[1,i[1]]*a[2,i[2])) -sum([i in antisymmetric(3)](a[0,i[0]]*a[1,i[1]]*a[2,i[2])); and the general nxn case can be written as det=sum([i in symmetric(n)](multiply([j in 0..n](a[j,i[j]]))) -sum([i in antisymmetric(n)](multiply([j in 0..n](a[j,i[j]]))); If the generator function is defined by a constant like symmetric(3) the loop should be unfolded at compiler time for optimal speed. D could use a interface for defining index generator functions such that this is possible.
Jan 08 2007
prev sibling next sibling parent Xinok <xnknet gmail.com> writes:
Warren D Smith Wrote:

 a <--> b;
 swaps a and b, same as making a tempvar t and then  t=a; a=b; b=t;
 As was pointed out by Robert W. Floyd ages ago, in his Turing award
 lecture (but nobody listened) this comes up so
 often it is worth having special syntax for it.

A few simpler symbols: <-> I think this would work best
<  Simpler, but the developer could possibly confuse this for another symbol

AFAIK, D makes no use of any of these.
Jan 08 2007
prev sibling next sibling parent %u <u digitaldaemon.com> writes:
== Quote from Warren D Smith (wds math.temple.edu)'s article
 is there a nice way to handle these without gotos?

Using lazy evaluation seems D-ish here: bool otherwise( lazy void dg) { dg; return false; } void main() { while( false || otherwise( printf("Falling through.\n")) ){ // if( something) break } printf( "breaking out.\n"); }
Jan 08 2007
prev sibling next sibling parent Daniel Keep <daniel.keep+lists gmail.com> writes:
Warren D Smith wrote:
 Here are some suggested improvements for D.
 
 a <--> b;
 swaps a and b, same as making a tempvar t and then  t=a; a=b; b=t;
 As was pointed out by Robert W. Floyd ages ago, in his Turing award
 lecture (but nobody listened) this comes up so
 often it is worth having special syntax for it.

As has been pointed out, you can write a swap function for this. Actually, what I'd really like to see is this being made possible: a,b = b,a; Yet another cool thing we could steal from Python :3
 labeled break and continue statements:
 that was a fine idea to eliminate a lot of gotos.
 HOWEVER, the most common way in which gotos happen that's not covered by D's
 break and continue is this:
 
 for(some loop condition){
   if(something){ goto A; }
 }
 fallthru_code;
 A:
 break_out_code;
 
 is there a nice way to handle these without gotos?   One possibility
 is to add a "default"
 block at ends of loops:
 for(some loop condition){
   if(something){ break; }
 }default{
   fallthru_code;
 }
 break_out_code;

What I've always wanted was this: for( blah ) { ... } else { ... } The same thing for all loops, actually. And while I'm here, these would be nice, too: foreach( foo ; bar ) { first { // Do something with first element }; else { // Do something with non-first elements }; }
 popcount and first1:
 ...

I'm sure every architecture could point to a cool opcode that isn't directly supported in any language and go "why not?" I won't say anything either way except: I don't really see the need.
 [Aside:
 Another excellent hardware instruction that as far as I know was never
 implemented is
 the "dovetail" and "undovetail" instructions
 which place the even-indexed bits of a word into a halfword, and the
 odd-index ones
 into another (undovetail) and dovetail is the reverse.]

I think there's some similar stuff in MMX/SSE, might be worth checking out.
 Undenying access to arithmetic:

I do agree that this is a cardinal sin of high level languages these days, but I wouldn't say they "deny" us access. It's more a case of "haven't worked out a good way of doing it". I mean, I'm not sure how to take
 c = a + b;

and come up with any half-decent syntax for adding the carry bit into the mix. Actually, I think the way most languages deal with numbers is a bit strange: "+" in D isn't *really* addition: it just looks like it 999 times out of 1000. So I *do* think we should be given access to things like the carry bits, and other features like it without having to resort to assembler, but I'm yet to see a good proposal on how to actually do so. (Libraries aren't a great solution since one of the reasons to use the carry bit is speed: and you just know that all those function calls aren't helping. That reminds me: can we have expression templates? ;P) -- Daniel
Jan 09 2007
prev sibling next sibling parent reply Don Clugston <dac nospam.com.au> writes:
Warren D Smith wrote:
 popcount and first1:
 Often one represents a set by means of an array of booleans, or
 equivalently by the bits of a machine word.
 Now, the cray used to have a wonderful "popcount" machine-instruction
  a = popcount(b);
 which would cause the number of 1-bits in the uint b, to be placed in
 the integer a.
 E.g. popcount(21)=3.
 Also, some machines had a "first1" instruction which would cause, e.g,
   c=0;
   printf("here are the locations of the 1bits in b: ");
   for(a = first1(b); b!=0; b >>= a){
      c += a;
      printf("%d,", c);
   }
   printf("\n");
 to work as a way to loop thru the elements of the set.
 
 This was all very fine.  It led to TREMENDOUS speedup and
 simplification of the right kinds of programs.
 BUT, later hardware got rid of the instruction and languages
 did not have these as features. 

We have first1 in the form of the bsf and bsr intrinsics. popcount is being added to X86 together with the next SSE revision, so it's coming back into hardware. I would like to see a library implementation of popcount added. Here's one I wrote some time ago: /** * Calculates the number of set bits in a 32-bit integer. * */ int bitcount(uint x) { // Avoid branches, and the potential for cache misses which // could be incurred with a table lookup. // We need to mask alternate bits to prevent the // sum from overflowing. // add neighbouring bits. Each bit is 0 or 1. x = x - ((x>>1) & 0x5555_5555); // now each two bits of x is a number 00,01 or 10. // now add neighbouring pairs x = ((x&0xCCCC_CCCC)>>2) + (x&0x3333_3333); // now each nibble holds 0000-0100. Adding them won't // overflow any more, so we don't need to mask any more // Now add the nibbles, then the bytes, then the words // We still need to mask to prevent double-counting. // Note that if we used a rotate instead of a shift, we // wouldn't need the masks, and could just divide the sum // by 8 to account for the double-counting. // On some CPUs, it may be faster to perform a multiply. x += (x>>4); x &= 0x0F0F_0F0F; x += (x>>8); x &= 0x00FF_00FF; x += (x>>16); x &= 0xFFFF; return x; } unittest { assert(bitcount(0)==0); assert(bitcount(7)==3); assert(bitcount(0xAA)==4); assert(bitcount(0x8421_1248)==8); assert(bitcount(0xFFFF_FFFF)==32); assert(bitcount(0xCCCC_CCCC)==16); assert(bitcount(0x7777_7777)==24); }
 [Aside:
 Another excellent hardware instruction that as far as I know was never
 implemented is
 the "dovetail" and "undovetail" instructions
 which place the even-indexed bits of a word into a halfword, and the
 odd-index ones
 into another (undovetail) and dovetail is the reverse.]

Great! I never had a name for those.
 Undenying access to arithmetic:
 hardware goes to a great amount of trouble to provide add-with-carry,
 multiply-two-singlewords-to-get-a-doubleword,
 long-division-with-quotient&remainder
 (if a is a doubleword divide a by b to get quotient q and remainder r,
 all singlewords), etc. to us.
 Another good thing available in a lot of hardware is shift-with-carry,
 and circular shift with and without carry.
 Why the hell does the language then tell the user to go screw
 themselves - we intend to deny
 you access to that power??!!!
 Hello?  This makes it very painful or
 difficult or slow
 to build a bignum package.  It is just gratuitously asinine.  If D
 delivered this it'd (a) be veyr easy, (b) instantly attract a lot of converts
 and you could build a portable bignum code that ran about 4
 times faster.

Rotations without carry would be very nice. But for the others, are there many applications of these OTHER than bignum arithmetic? My feeling is that you'd always want to do bignum in asm anyway. Note that D is a great language for writing asm in; you can have a single source code shared between Windows, *nix, and the new x86 Macs.
Jan 09 2007
next sibling parent Warren D Smith <wds math.temple.edu> writes:
reply to Don Clugston

Yes, the "repeated doubling of wisdom"
bitcount routine you wrote is a good way to do it.
Also, more brute-force, but on many machines faster, is to use
precomputed popcount lookup tables.

Lookup tables can also be used to implement first1, and so
can a "repeated wisdom doubling" approach to implement a binary search.
Another way to do first1(uint x) is first to compute  y=x^(x-1)   which if x!=0
is a uint with a single 1 bit located at the same place as the
least-significant 1 bit in x, and second to hash y, for example
use y%C as the hash function [value in {0..C-1}] and you cleverly choose the
constant C so that this hash function always gives different values
for different y of this form (i.e. perfect hash)
and do a hash-table lookup in a C-entry table.
If I recall right, which I may not, C=63 works.
Unfortunately the "%" is slow on the hardware I used.

All that is suckingly slow compared to hardware support, though.

--

Are there many applications of [add with carry, etc]
OTHER than bignum arithmetic? My
feeling is that you'd always want to do bignum in asm anyway.

Note that D is a great language for writing asm in; you can have a
single source code shared between Windows, *nix, and the new x86 >Macs.

But I want to write PORTABLE, i.e. not-asm, bignum code. Why is the language denying me the power of the machine? That is the opposite of its job. Especially if we are talking about a power that every machine provides. It is kind of like saying: "you can only breathe air from now on, if you use a gas mask. This is a great advance in technology versus just breathing, so be happy." The other main application of add-with-carry is to spot integer overflow. Look, if you just provide, e.g. AddWithCarry( in uint x, in uint y, out uint z, out bool carry ) DoubleMultiply( in uint32 x, in uint32 y, out uint64 z ) [or maybe two out-arguments, an uper and lower one] FullDivide( in uint64 y, in uint32 z, out uint32 quotient, out uint32 remainder ) and similar stuff, problem is over. (Ignore my crappy syntax, just use this idea but with better syntax.)
Jan 09 2007
prev sibling next sibling parent reply Don Clugston <dac nospam.com.au> writes:
Witold Baryluk wrote:
 Tabelarising number of nonzero bits in char[256], and
 applying it to each 8bit group in 32bit integer, can be quicker.

It can be (and certainly was always true in the days of the 286), but table lookups always run the risk of falling out of the data cache (and this is something a simple benchmark won't find). On most recent CPUs, cache misses are horribly expensive, and even one cache miss every 1000 calls will easily wipe out any small performance benefits you'd otherwise expect from the table lookup.
Jan 09 2007
parent reply Warren D Smith <wds math.temple.edu> writes:
Unfortunately the response to my "suggested improvements to D,"
oddly, was not uniformly "of course we'll do that immediately."

Let me reiterate my case.  First, D'ers have already agreed by consensus to add
IEEE-float hooks to handle NaNs, rounding, etc.
Good.  That means you already have admitted you
agree with my philosophy that the language
must provide the underlying power of the machine (for any feature
that a large number of machine hardwares now supply) to the user.
Not deny it.
And that means you agree this has to be done even if the syntax
for it might be a little messy. [Which doesn't matter because these
things are used fairly rarely.]

Good.  I'm glad we are in agreement.  I only ask that you now
provide hooks to allow the user to access add-with-carry, cyclic-shift
with or without carry, integer-single-to-doubleword-multiply, doublelength
divide,
etc.  Because those things have been available for far longer than IEEE floating
point on far more hardware and are doable with (if anything) less-messy hooks,
you
cannot logically provide the IEEE FP hooks but not these; that would be going
back
on 50 years of computing wisdom and on your own admitted beliefs.

OK?  There is no question.  D'ers already agreed on this philosophy.

Next, some wondered about popcount and first1 hooks.
But then it was pointed out that, again, my opponents on this
had already lost their case - Intel soon is going to provide
these, again, in hardware, because they agree with me that they
are key instructions.  Good.  Now, referrring again to the principle
(above) that the language must provide (not deny) the underlying
power of the machine to users, again we see you have no
choice but to provide these hooks (unless you choose to go back on
your own admitted philosophy).

After you do these things, you will then be able to add to your D vs X language
comparison charts, the fact D is the only one that does not deny user access to
common hardware primitives.  (And no, sorry:
saying "you can do it by writing your own assembler" does not count as
"we provide access in the higher level language.")

This new feature of your comparison chart will
attract a multitude of users who are impressed with the fact that
finally, the designers of a language are not intentionally trying
to hurt people.

Won't that be nice?

There are even those who would go further and advocate that higher
level languages should even provide the user with access to
features NOT currently hardware-supported, but which should be,
or likely will be in future.   Thus allowing software to
drive the hardware.  Stupendous idea, is it not?
For example, microsoft BASIC provided the user the ability to multiply and
divide
numbers, even though that was not available on the 8080 in hardware.  Golly gee.
Wasn't that amazing.
If D wishes to use that idea, then it might even provide
some hooks for some hardware instructions that do not currently exist,
but which have been argued in important papers (which sadly have not
yet penetrated the thick skulls of hardware designers)
to be a good thing which SHOULD exist.
The "dovetail" and "undovetail" instructions would be examples
(known to be useful in some important algorithms...),
and I could mention a few more if anybody shows interest,
e.g. instructions known to be useful to yield sub-NlogN sorting algorthms, etc.

But I do not wish to stretch you too far.  After all,
catching up to Microsoft circa 1980 in the area of language design
ideas, could be too much to ask.  Therefore, I merely ask that
D catch up to the computer hardware available in the 1980s, or
for that matter 1950s.

(Seriously: D seems to me to be pretty much making the right choices
and I've been waiting for a language with that combination of choices for over a
decade, so it'd be a pity to see D fall into the same pit of stupidity as all
the
others about such an embarrassingly trivial task as providing a few builtin
inline
functions.)

wds
Jan 10 2007
next sibling parent BCS <ao pathlink.com> writes:
Reply to Warren,

 Unfortunately the response to my "suggested improvements to D," oddly,
 was not uniformly "of course we'll do that immediately."
 
 Let me reiterate my case.  First, D'ers have already agreed by
 consensus to add  IEEE-float hooks to handle NaNs, rounding, etc.
 Good.  That means you already have admitted you agree with my 
 philosophy that the language must provide the underlying power 
 of the machine (for any feature that a large number of machine 
 hardwares now supply) to the user. Not deny it.

No it dose not.
 OK?  There is no question.  D'ers already agreed on this philosophy.

This whole thread isn't based on the basic philosophy of D, so I claim that the above is in serious question. (more on this later)
 And that means you agree this has to be done even if the syntax
 for it might be a little messy. [Which doesn't matter because these
 things are used fairly rarely.]
 Good.  I'm glad we are in agreement. 

We are? Starting when? I must have missed that meeting. [...]
 finally, the designers of a language are not intentionally trying
 to hurt people.
 Won't that be nice?

Only BF, whitespace, intercal and friends TRY to hurt programmers.
 it'd be a pity to see D fall into the same pit of stupidity as all the
 others about such an embarrassingly trivial task as providing a few
 builtin inline functions.)

Firstly, ANY change to the core of a language is by definition non trivial. A better solution is intrinsics, particularly if (in the ops using carry) they take the forms: void adc(uint* a, uint* b, uint* sum, uint count) As to you claims that not adding these features is counter to the D philosophy, I have written my take on the D philosophy in a paper (link below) and I don't think your claim has support. If I have a erroneous opinion, I would hope some of the long timers would correct me, or if you think that what you are advocating /does/ fall under my opinion of the D philosophy I would entertain you thoughts. http://www.webpages.uidaho.edu/~shro8822/term_010.pdf Note: this paper is still in progress. BCS
 wds
 

Jan 10 2007
prev sibling parent Don Clugston <dac nospam.com.au> writes:
Warren D Smith wrote:
 Unfortunately the response to my "suggested improvements to D,"
 oddly, was not uniformly "of course we'll do that immediately."
 
 Let me reiterate my case.  First, D'ers have already agreed by consensus to add
 IEEE-float hooks to handle NaNs, rounding, etc.
 Good.  That means you already have admitted you
 agree with my philosophy that the language
 must provide the underlying power of the machine (for any feature
 that a large number of machine hardwares now supply) to the user.
 Not deny it.

Indeed, it's always been part of the philosophy of D (that's why D supports 80-bit reals, for example). About six months ago, Walter said that he does intend to add more intrinsics, but that it's a difficult thing to do, so it's been pushed down on the list of priorities. Don't worry, it will happen eventually. But certainly not immediately.
Jan 10 2007
prev sibling parent Sebastian Biallas <groups.5.sepp spamgourmet.com> writes:
Don Clugston wrote:
 Rotations without carry would be very nice. 

Rotations without carry are available if the compiler recognizes the common idioms: gcc recognizes: unsigned int foo(unsigned int u) { return u << 16 | u >> 16; } (will make a rotate instruction, if possible)
Jan 11 2007
prev sibling next sibling parent reply BCS <ao pathlink.com> writes:
Reply to Warren,

 Here are some suggested improvements for D.
 

 labeled break and continue statements:
 that was a fine idea to eliminate a lot of gotos.
 HOWEVER, the most common way in which gotos happen that's not covered
 by D's
 break and continue is this:
 for(some loop condition){
 if(something){ goto A; }
 }
 fallthru_code;
 A:
 break_out_code;

loop: while(false) { for(some loop condition) { if(something) break loop; } fallthru_code; } break_out_code; the dummy labeled loop body might be just useful enough to make this legal bod: { // labeled compound statement if(cond) break bod; else continue bod; }
Jan 09 2007
parent reply Warren D Smith <wds math.temple.edu> writes:
reply to BCS's reply

actually you meant this:
loop: do{
  for(some loop condition){
    if(something) break loop;
  }
  fallthru_code;
}while(false);
break_out_code;

which I agree solves my problem without gotos, but at the cost of ugliness.  So
I
guess the best solution is if a less-ugly way were supported to do this same
thing.
We could have a DoItOnce{ ... }  pseudo-loop (which never loops)
syntax to replace do{ ... }while(false);  but that still is ugly.
So your suggestion for this syntax is a good one:

bod: {     // labeled compound statement
   if(cond) break bod;
}

except I do not see the point (or syntactical meaning,
for that matter) of having "continue bod" if bod is not
manifestly a loop.   This simple suggestion of being
able to break out of any block, would
eliminate practically all the remaining gotos in the world.
Excellent idea.
Jan 09 2007
next sibling parent BCS <ao pathlink.com> writes:
Reply to Warren,

 reply to BCS's reply
 
 actually you meant this:
 loop: do{
 for(some loop condition){
 if(something) break loop;
 }
 fallthru_code;
 }while(false);
 break_out_code;
 

Oops. [...]
 So your suggestion for this syntax is a good one:
 bod: {     // labeled compound statement
 if(cond) break bod;
 }
 except I do not see the point (or syntactical meaning,
 for that matter) of having "continue bod" if bod is not
 manifestly a loop.   

The thought is it would be the same as in a while(true), go back to the start of the loop. It could be handy with some kids of loops // keep (re)doing things in order until all conditions are met. bod: { //somthing if(cond1) continue bod; //somthing if(cond2) continue bod; //somthing if(cond3) continue bod; //somthing if(cond4) continue bod; } this would work but isn't as informative. while(true){ //somthing if(cond1) continue bod; //somthing if(cond2) continue bod; //somthing if(cond3) continue bod; //somthing if(cond4) continue bod; break; }
 This simple suggestion of being
 able to break out of any block, would
 eliminate practically all the remaining gotos in the world.
 Excellent idea.

Jan 09 2007
prev sibling parent reply %u <u uuu.uuu> writes:
== Quote from Warren D Smith (wds math.temple.edu)'s article
 So your suggestion for this syntax is a good one:
 bod: {     // labeled compound statement
    if(cond) break bod;
 }

Wrong. The keyword "break" only became a synonym for "goto"; the inherent shortcomings of goto's are not solved this way. (Proof left to the reader.)
Jan 09 2007
parent reply Warren D Smith <wds math.temple.edu> writes:
 So your suggestion for this syntax is a good one:
 bod: {     // labeled compound statement
    if(cond) break bod;
 }


Wrong. The keyword "break" only became a synonym for "goto"; the
inherent shortcomings of goto's are not solved this way. (Proof
left to the reader.)

--No, Mr. Anonymous - you're completely wrong. Gotos can spaghetti, form arbitrary directed network. Breaks out of blocks, can only get you out of a block, i.e. moving up in the inclusion hierarchy - can never go in, i.e. never down in the hierarchy. I would, however, say that the bod: { ... } syntax is psychologically annoying and I might prefer bod: block{ ... } or something. wds
Jan 09 2007
parent reply %u <u uuu.uuu> writes:
== Quote from Warren D Smith (wds math.temple.edu)'s article
 --No, Mr. Anonymous - you're completely wrong.
 Gotos can spaghetti, form arbitrary directed network.
 Breaks out of blocks, can only get you out
 of a block

I hold my breath! Do you really declare that the Chomsky hierarchy is wrong---missing a complete type of infinite languages since ages?
Jan 10 2007
parent BCS <ao pathlink.com> writes:
Reply to %u,

 I hold my breath!
 Do you really declare that the Chomsky hierarchy is wrong---missing
 a complete type of infinite languages since ages?

As the Chomsky hierarchy uses names like "type-n /grammar/" it would seem that it deals with syntax. The use of gotos vs. break is a semantic issues and as such has no barring on syntax classifications
Jan 10 2007
prev sibling parent Witold Baryluk <baryluk mpi.int.pl> writes:
Tabelarising number of nonzero bits in char[256], and
applying it to each 8bit group in 32bit integer, can be quicker.

-- 
Witold Baryluk
Jan 09 2007