karl@haddock.ima.isc.com (Karl Heuer) (03/16/90)
In article <5819.25f7a840@vax1.tcd.ie> cbuckley@vax1.tcd.ie writes: >In article <Mar.7.10.43.42.1990.17402@paul.rutgers.edu>, emuleomo@paul.rutgers.edu (Emuleomo) writes: >> The other less serious flaw in C is the do...while contruct. >> I kind of prefer PASCAL's repeat....until construct myself. > >How can this be a flaw? The two constructs are identical except for the fact >that the condition is reversed... That's enough to make it a (minor) flaw. Judging from my own personal experience, it is more natural for a test-at-top loop to specify the condition for continuing (while), but for a test-at-bottom loop to specify the condition for terminating (until). I don't know if there's been a study on this; in fact, I'm not entirely sure how to formalize the concept. And no, I did *not* learn Pascal before C. At worst, my opinion may be slightly polluted from Ratfor; but I believe there's a sense in which repeat...until is really better. Karl W. Z. Heuer (karl@ima.ima.isc.com or harvard!ima!karl), The Walking Lint Followups to comp.lang.misc.
pmontgom@oak.math.ucla.edu (Peter Montgomery) (03/16/90)
In article <16188@haddock.ima.isc.com> karl@haddock.ima.isc.com (Karl Heuer) writes: >In article <5819.25f7a840@vax1.tcd.ie> cbuckley@vax1.tcd.ie writes: >>In article <Mar.7.10.43.42.1990.17402@paul.rutgers.edu>, emuleomo@paul.rutgers.edu (Emuleomo) writes: >>> The other less serious flaw in C is the do...while contruct. >>> I kind of prefer PASCAL's repeat....until construct myself. >> > >That's enough to make it a (minor) flaw. Judging from my own personal >experience, it is more natural for a test-at-top loop to specify the condition >for continuing (while), but for a test-at-bottom loop to specify the condition >for terminating (until). I don't know if there's been a study on this; in >fact, I'm not entirely sure how to formalize the concept. Another problem with do..while is that we cannot access variables declared inside the block in the loop test. For example, when updating a square root by Newton's method, the code double sqrtx, x; sqrtx = (some approximation to sqrt(x)) do { register const double err = x - sqrtx*sqrtx; sqrtx += err/(2*sqrtx); } while (fabs(err) > 0.001*x); is illegal. Rather, we must declare "err" in a larger scope. -------- Peter Montgomery pmontgom@MATH.UCLA.EDU Department of Mathematics, UCLA, Los Angeles, CA 90024
ryan@sjuphil.uucp (Patrick M. Ryan) (03/16/90)
In article <16188@haddock.ima.isc.com> karl@haddock.ima.isc.com (Karl Heuer) writes: >In article <5819.25f7a840@vax1.tcd.ie> cbuckley@vax1.tcd.ie writes: >>In article <Mar.7.10.43.42.1990.17402@paul.rutgers.edu>, emuleomo@paul.rutgers.edu (Emuleomo) writes: >>> The other less serious flaw in C is the do...while contruct. >>> I kind of prefer PASCAL's repeat....until construct myself. >> >That's enough to make it a (minor) flaw. Judging from my own personal >experience, it is more natural for a test-at-top loop to specify the condition >for continuing (while), but for a test-at-bottom loop to specify the condition >for terminating (until). I don't know if there's been a study on this; in >fact, I'm not entirely sure how to formalize the concept. a simple hack to fix this problem: #define repeat do #define until(c) while (!(c)) thus, repeat { do { statement; becomes statement; until(condition); while (!(condition)) easy, no? -- patrick m. ryan saint joseph's ryan@sju.edu / ryan%sjuphil.sju.edu@bpa.bell-atl.com university {bpa|burdvax|princeton|rutgers}!sjuphil!ryan philadelphia pmr@gemini.gsfc.nasa.gov pennsylvania
flint@gistdev.gist.com (Flint Pellett) (03/16/90)
I have always felt that the re-use of the "while" keyword for both the top and the bottom of a loop was a language flaw, as is reusing "break" for both exiting cases and loops. When you are looking at a 70-line loop (so you can't see the whole loop on one screen) often the only clue you have whether that "while" you are looking at is the bottom or the top of a loop is whether or not a } preceeds the while on the same line, and some people's coding styles don't guarantee that. (I keep it straight by having a while that ends a loop always have the } right before it.) I have to admit to liking the construct below for loops the best: (On any of these leaving the (condition) out is the same as if the condition were true, except for endloop, where the default is an unconditional branch back to the loop.) loop (condition) /* keep looping as long as the condition is met */ ... outloop (condition) /* 'break' if the condition is met */ ... reloop (condition) /* 'continue' back at the "loop" if condition met */ ... endloop (condition) /* exit the loop now if the condition is met */ The four keywords above make it very clear what you are doing at each step, even when you cannot look at the entire loop at once. (You never have to wonder if that 'break' goes with a 'case' or with a 'while' either in those cases where only the break is on your screen.) -- Flint Pellett, Global Information Systems Technology, Inc. 1800 Woodfield Drive, Savoy, IL 61874 (217) 352-1165 INTERNET: flint%gistdev@uxc.cso.uiuc.edu UUCP: uunet!gistdev!flint
cet1@cl.cam.ac.uk (C.E. Thompson) (03/16/90)
In article <16188@haddock.ima.isc.com> karl@haddock.ima.isc.com (Karl Heuer) writes: >In article <5819.25f7a840@vax1.tcd.ie> cbuckley@vax1.tcd.ie writes: >>In article <Mar.7.10.43.42.1990.17402@paul.rutgers.edu>, emuleomo@paul.rutgers.edu (Emuleomo) writes: >>> The other less serious flaw in C is the do...while contruct. >>> I kind of prefer PASCAL's repeat....until construct myself. >> >>How can this be a flaw? The two constructs are identical except for the fact >>that the condition is reversed... > >That's enough to make it a (minor) flaw. Judging from my own personal >experience, it is more natural for a test-at-top loop to specify the condition >for continuing (while), but for a test-at-bottom loop to specify the condition >for terminating (until). I don't know if there's been a study on this; in >fact, I'm not entirely sure how to formalize the concept. Time for another BCPL-was(is)-better-than-C plug. BCPL has WHILE expression DO command UNTIL expression DO command command REPEATWHILE expression command REPEATUNTIL expression and of course command REPEAT /* for ever */ But you probably wanted to use some of those reserved words as variable names, right? :-) Chris Thompson JANET: cet1@uk.ac.cam.phx Internet: cet1%phx.cam.ac.uk@nsfnet-relay.ac.uk
wittig@gmdzi.UUCP (Georg Wittig) (03/19/90)
pmontgom@oak.math.ucla.edu (Peter Montgomery) writes: > Another problem with do..while is that we cannot access >variables declared inside the block in the loop test. For example, >when updating a square root by Newton's method, the code > double sqrtx, x; > sqrtx = (some approximation to sqrt(x)) > do { > register const double err = x - sqrtx*sqrtx; > sqrtx += err/(2*sqrtx); > } while (fabs(err) > 0.001*x); >is illegal. Rather, we must declare "err" in a larger scope. No, you needn't. The problem can be avoided easily: double sqrtx, x; sqrtx = (some approximation to sqrt(x)) do { register const double err = x - sqrtx*sqrtx; sqrtx += err/(2*sqrtx); if(! (fabs(err) > 0.001*x)) break; /* HA! */ } while (1); -- Georg Wittig GMD-Z1.BI P.O. Box 1240 D-5205 St. Augustin 1 (West Germany) email: wittig@gmdzi.uucp phone: (+49 2241) 14-2294 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - "Freedom's just another word for nothing left to lose" (Kris Kristofferson)
karl@haddock.ima.isc.com (Karl Heuer) (03/22/90)
(Followups to comp.lang.misc. I'm not talking about C; I'm talking about loop constructs in general.) In <OVB2S3Bxds13@ficc.uu.net> peter@ficc.uu.net (Peter da Silva) writes: >The only sense in which repeat...until is more natural than do...while is >if you're an assembly programmer or compiler writer [because at a low level, >both are branch-if-false]. That's one possible justification, but it certainly isn't "the only sense" in which it's more natural. To take a concrete example, let's ignore the existence of <ctype.h> and suppose that we want to test whether or not a given character is a lowercase letter. I claim that, to me, the condition "(c >= 'a' && c <= 'z')" is a simpler expression than "(c < 'a' || c > 'z')". I immediately recognize the idiom in the former, but the latter causes a perceptible delay as I mentally translate the condition. (If you disagree with this example, invent another one--unless you want to claim that there is *no* condition that is simpler than its inverse.) Now, my observation is that, given a condition COND which is simpler than !COND, I am more likely to encounter the condition "do...while (!COND)" than "do...while (COND)". In this sense, repeat...until is the more natural construct. This is not a proof. It's an observation, possibly biased (though I don't think so) and subject to being contradicted by a more extensive study. Karl W. Z. Heuer (karl@ima.ima.isc.com or harvard!ima!karl), The Walking Lint ________ (Note to those who keep on beating this red herring: the difference is *not* so significant that I'm willing to use it as an excuse to switch from C to another language; not even to that dialect of C that uses an "until" macro. So don't bother to point out that "the preprocessor can fix it". Do you think you're telling me something I don't know?)
mph@lion.inmos.co.uk (Mike Harrison) (03/23/90)
In article <16249@haddock.ima.isc.com> karl@haddock.ima.isc.com (Karl Heuer) writes: >(Followups to comp.lang.misc. I'm not talking about C; I'm talking about loop >constructs in general.) > ... >To take a concrete example, let's ignore the existence of <ctype.h> and >suppose that we want to test whether or not a given character is a lowercase >letter. I claim that, to me, the condition "(c >= 'a' && c <= 'z')" is a >simpler expression than "(c < 'a' || c > 'z')". I immediately recognize the >idiom in the former, but the latter causes a perceptible delay as I mentally >translate the condition. (If you disagree with this example, invent another >one--unless you want to claim that there is *no* condition that is simpler >than its inverse.) But how about: subtype LOWER_CASE_LETTERS is CHARACTER range 'a' .. 'z'; C : CHARACTER; GET(C); if C in LOWER_CASE_LETTERS then ... (Guess which language :-)) For loop control structures I always liked Algol 68, where you could do all the work in the Condition part, with an empty loop body, eg: 'while' 'if' a[i] > i 'then' i +:= 1; 'true' 'else' 'false' 'fi' 'do' 'skip' 'od' And for the ultimate in conditional expressions: 'if' x = 1 'then' y 'else' z 'fi' := x; Mike, Michael P. Harrison - Software Group - Inmos Ltd. UK. ----------------------------------------------------------- UK : mph@inmos.co.uk with STANDARD_DISCLAIMERS; US : mph@inmos.com use STANDARD_DISCLAIMERS;
meissner@osf.org (Michael Meissner) (03/24/90)
In article <4879@ganymede.inmos.co.uk> mph@lion.inmos.co.uk (Mike Harrison) writes: | >To take a concrete example, let's ignore the existence of <ctype.h> and | >suppose that we want to test whether or not a given character is a lowercase | >letter. I claim that, to me, the condition "(c >= 'a' && c <= 'z')" is a | >simpler expression than "(c < 'a' || c > 'z')". I immediately recognize the | >idiom in the former, but the latter causes a perceptible delay as I mentally | >translate the condition. (If you disagree with this example, invent another | >one--unless you want to claim that there is *no* condition that is simpler | >than its inverse.) Three things: 1) On EBCDIC systems, either of the above tests would evaluate true for some things that are not lower case alphabetic, since there are some characters (10?) between 'i' & 'j'; 2) Obviously the above test will not work for character sets that have more than 26 alphabetic characters; 3) If you are worried about micro optimization, and your compiler doesn't recognize the optimization, you generally get faster code if you rewrite the test as: if (((unsigned) c - 'a') <= ((unsigned) 'z' - 'a')) This is because only one branch is done. -- Michael Meissner email: meissner@osf.org phone: 617-621-8861 Open Software Foundation, 11 Cambridge Center, Cambridge, MA Catproof is an oxymoron, Childproof is nearly so
karl@haddock.ima.isc.com (Karl Heuer) (03/26/90)
In article <MEISSNER.90Mar24084404@curley.osf.org> meissner@osf.org (Michael Meissner) writes: >In article <4879@ganymede.inmos.co.uk> mph@lion.inmos.co.uk (Mike Harrison) writes: >|>To take a concrete example, let's ignore the existence of <ctype.h> and >|>suppose that we want to test whether or not a given character is a lowercase Watch those attributions! Mike H. didn't say that; I did. >Three things: [why (c >= 'a' && c <= 'z') is an imperfect test] Agreed. What I said above was shorthand for "for the sake of this example, let's ignore the fact that <ctype.h> exists and is probably a better tool for the job." In any case, my point stands: `until' seems to be better than `while', for most of those test-at-bottom loops where the condition is complex enough to make a difference. Karl W. Z. Heuer (karl@ima.ima.isc.com or harvard!ima!karl), The Walking Lint