Warning: mysqli::__construct(): (HY000/1203): User howardkn already has more than 'max_user_connections' active connections in D:\Inetpub\vhosts\howardknight.net\al.howardknight.net\includes\artfuncs.php on line 21
Failed to connect to MySQL: (1203) User howardkn already has more than 'max_user_connections' active connectionsPath: ...!weretis.net!feeder9.news.weretis.net!news.quux.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!eternal-september.org!.POSTED!not-for-mail From: Kaz Kylheku <643-408-1753@kylheku.com> Newsgroups: comp.lang.c Subject: Re: Loops (was Re: do { quit; } else { }) Date: Tue, 15 Apr 2025 13:19:52 -0000 (UTC) Organization: A noiseless patient Spider Lines: 152 Message-ID: <20250415053852.166@kylheku.com> References: <20250409142303.00004645@yahoo.com> <87ikndqabc.fsf@nosuchdomain.example.com> <20250410115501.000037a5@yahoo.com> <20250410080629.532@kylheku.com> <87a58mqt2o.fsf@nosuchdomain.example.com> <20250413072027.219@kylheku.com> Injection-Date: Tue, 15 Apr 2025 15:19:53 +0200 (CEST) Injection-Info: dont-email.me; posting-host="16520bcd085ba48f48bf86c676aa114c"; logging-data="3987935"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19zKG+RmMwG1e2zjXl2rvwO1/YmmY3w+nw=" User-Agent: slrn/pre1.0.4-9 (Linux) Cancel-Lock: sha1:5Ezk7VVcn5oOO1hyv6Xl5AC45rQ= Bytes: 6847 On 2025-04-15, bart wrote: > On 15/04/2025 08:17, Janis Papanagnou wrote: >> and someone already posted another iteration type on linked lists >> >> for (node = list; node; node = node->next) > > These two I get, and I can tell you that they're all WHILE loops. To > make make them tidier, I'd have fewer complaints about them if they > instead looked like this: > > while (node = list; node; node = node->next) That's mostly bike shedding. It could also have been called: do (node = list; node; node = node->next) loop (node = list; node; node = node->next) Lisp called this kind of general variable stepping loop "do" (do ((var1 init1 step1) (var2 init1 step2) ...) (until-this-is-true also-this ... yield-this-result) do-this and-this ...) Naming things can be hard. The reason that the loop is called for is that most instance of for have a focus on the specific variable that is initialized, and the guard condition has to do with it hitting some specific terminating value. > So, you can optionally add extra elements to a while (x). > > It would be necessary to either define whether while(x; y) means while > (; x; y) or while (x; y), or to always require either zero or two > semicolons inside (...). > > That could have kept 'for' for how it works in other languages (the ones > that haven't just blindly copied C's version!). Common Lisp uses "for" to indicate several kinds of variable stepping clauses inside the loop syntax, some of which are: [4]> (loop for x in '(a b c) for y = 1 then (1+ y) for z = (* y 10) with w = (* y 10) collect (list x y z w)) ((A 1 10 10) (B 2 20 10) (C 3 30 10)) When loop is used to simulate the classic Lisp do loop, it's done with the "for var = init then step" clauses. There is a "for var from N to M" clause, as well as "for var below N" which goes from 0 to N-1. Why the C for loop is called "for" is that it is oriented toward variable stepping. The while part of it is just the termination test. for (node = list, count = 0; node; node = node->next, count++) ... While loops occur that are not focused on stepping specific variables: while (!(*status_port & CTS)) { } while (queue_empty(q)) cond_wait(&condvar, &mutex); > Let me ask you this: what exactly is the point of the 'while' statement > in C? > Since it can always be trivially be written as: > for (;cond;) That is simply untidy looking. If C had a preprocessor from the beginning, while could have ben defined as: #define while(cond) for(;cond;) There are still some reasons not to do that, and preprocessing came later. > It seems to that most use cases (initialise, check exit condition, > change something that affects the letter), would suit 'for' better. The new for can declare a variable. This is important in macros because the loop header encloses the declaration, such that it cannot accidentally tear away as a fragment of another statement: This macro: #define step(type, var, from, to) for(type var = from; var <= to; var ++) cannot be defined using while without issues. #define step(type, var, from, to) type var = from; while (var <= to; var ++) Yes; we can make a macro #define whl(cond) for (;cond;) > > But since 'for' then becomes overloaded, there ought to be a dedicated > feature for simple iteration. Once the macro preprocessor was introduced, programmers met their need for dedicated, simplified iteration constructs that way, albeit imperfectly. // step n for each node in list list_for (n, list) { .... } #define list_for(n, list) for (node n = list; n; n = n->next) A lot of these kinds of macros have issues of hygiene; we wouldn't want them in a standard header file. They serve well the specific codebase they are in, and that's all that can be said for them. >>> Suppose you see 'i <= N' as the condition; is that '<=' intentional, or >>> is it a typo for '<'? It's impossible to tell. >> >> (This is nonsense.) > > You can't just say that without explanation. WHY it it nonsense? Take this: > > for (i=0 i<=N; ++i) It isn't nonsense. Guard conditions in for loops have historically been a source of off-by-one errors in C programming, which bears acknowledging. > Most such loops iterate over 0..N-1 inclusive, so would need "<". So, in > your opinion, is that <= a typo, or is the intention to iterate over > 0..N inclusive (so N+1 iterations)? Indeed in a "for i from 0 to n + 1" type construct, it is vanishingly unlikely that n + 1 is a typo. It may be wrong, but as a finger slip-up that the eyes didn't catch. -- TXR Programming Language: http://nongnu.org/txr Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal Mastodon: @Kazinator@mstdn.ca