www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - OT: for (;;) {} vs while (true) {}

reply Dennis Ritchie <dennis.ritchie mail.ru> writes:
Hi all,

In the source code, written in D, is often used in the design of 
the `for (;;) { ... }`

Maybe someone has specific examples of translation of code in 
asm, where `while (true) { ... }` or `for (;;) { ... }` affect 
the performance or cross-platform programs.
It would be interesting to see samples.
Nov 24 2016
next sibling parent reply LiNbO3 <nosp m.please> writes:
On Thursday, 24 November 2016 at 21:57:15 UTC, Dennis Ritchie 
wrote:
 Hi all,

 In the source code, written in D, is often used in the design 
 of the `for (;;) { ... }`

 Maybe someone has specific examples of translation of code in 
 asm, where `while (true) { ... }` or `for (;;) { ... }` affect 
 the performance or cross-platform programs.
 It would be interesting to see samples.
As you can see [1] the `while (true)` is lowered into `for (;true;)` so it's all about what construct pleases you the most. [1] https://github.com/dlang/dmd/blob/cd451ceae40d04f7371e46df1c955fd914f3085f/src/statementsem.d#L357
Nov 24 2016
parent reply Dennis Ritchie <dennis.ritchie mail.ru> writes:
On Thursday, 24 November 2016 at 22:04:00 UTC, LiNbO3 wrote:
 As you can see [1] the `while (true)` is lowered into `for 
 (;true;)` so it's all about what construct pleases you the most.

 [1] 
 https://github.com/dlang/dmd/blob/cd451ceae40d04f7371e46df1c955fd914f3085f/src/statementsem.d#L357
OK, thanks. The next question is: What principles guided when choosing between `for (;;) { ... }` and `while (true) { ... }` ? For example, there are two options: https://github.com/dlang/phobos/blob/master/std/algorithm/sorting.d
Nov 24 2016
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 11/24/2016 05:09 PM, Dennis Ritchie wrote:
 On Thursday, 24 November 2016 at 22:04:00 UTC, LiNbO3 wrote:
 As you can see [1] the `while (true)` is lowered into `for (;true;)`
 so it's all about what construct pleases you the most.

 [1]
 https://github.com/dlang/dmd/blob/cd451ceae40d04f7371e46df1c955fd914f3085f/src/statementsem.d#L357
OK, thanks. The next question is: What principles guided when choosing between `for (;;) { ... }` and `while (true) { ... }` ? For example, there are two options: https://github.com/dlang/phobos/blob/master/std/algorithm/sorting.d
I wouldn't ding anyone in a code review for using one vs the other. -- Andrei
Nov 24 2016
prev sibling next sibling parent reply Claude <no no.no> writes:
On Thursday, 24 November 2016 at 22:09:22 UTC, Dennis Ritchie 
wrote:
 On Thursday, 24 November 2016 at 22:04:00 UTC, LiNbO3 wrote:
 As you can see [1] the `while (true)` is lowered into `for 
 (;true;)` so it's all about what construct pleases you the 
 most.

 [1] 
 https://github.com/dlang/dmd/blob/cd451ceae40d04f7371e46df1c955fd914f3085f/src/statementsem.d#L357
OK, thanks. The next question is: What principles guided when choosing between `for (;;) { ... }` and `while (true) { ... }` ? For example, there are two options: https://github.com/dlang/phobos/blob/master/std/algorithm/sorting.d
Between "for(;;)", "while(true)" and "do while(true)", I would use the "while (true) { }" for pure readability and semantic reasons. I reckon "for(;;)" form is used for debug reasons (so you can easily insert conditions to transform an infinite loop into a finite one).
Nov 25 2016
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 25.11.2016 11:33, Claude wrote:
 ...

 Between "for(;;)", "while(true)" and "do while(true)", I would use the
 "while (true) { }" for pure readability and semantic reasons.
 ...
What semantic reasons?
 I reckon "for(;;)" form is used for debug reasons (so you can easily
 insert conditions to transform an infinite loop into a finite one).
You can just as easily edit the while condition. I use it because "unconditional loop" is less silly than "loop until true is false".
Nov 25 2016
next sibling parent reply Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Friday, November 25, 2016 12:10:44 Timon Gehr via Digitalmars-d wrote:
 On 25.11.2016 11:33, Claude wrote:
 ...

 Between "for(;;)", "while(true)" and "do while(true)", I would use the
 "while (true) { }" for pure readability and semantic reasons.
 ...
What semantic reasons?
Probably the complete lack of a condition to test in for(;;). I confess that I was shocked when I found out that it was legal to have a for loop without a condition. That seems like doing while() or if(), which makes no sense. So, I never use for(;;) and wish that it didn't exist, but it does, and some folks use it. So, I have to live with the possiblity of dealing with it when dealing with code written by other people. But I won't ever use it. - Jonathan M Davis
Nov 25 2016
parent reply Dennis Ritchie <dennis.ritchie mail.ru> writes:
On Friday, 25 November 2016 at 11:20:24 UTC, Jonathan M Davis 
wrote:
 Probably the complete lack of a condition to test in for(;;). I 
 confess that I was shocked when I found out that it was legal 
 to have a for loop without a condition. That seems like doing 
 while() or if(), which makes no sense. So, I never use for(;;) 
 and wish that it didn't exist, but it does, and some folks use 
 it. So, I have to live with the possiblity of dealing with it 
 when dealing with code written by other people. But I won't 
 ever use it.
IMO, it is very convenient for system programming guru. It is believed that it came from the K&R. For example, this option is definitely very convenient to use: https://github.com/dlang/phobos/blob/master/std/algorithm/comparison.d#L591
Nov 25 2016
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 11/25/2016 07:53 AM, Dennis Ritchie wrote:
 On Friday, 25 November 2016 at 11:20:24 UTC, Jonathan M Davis wrote:
 Probably the complete lack of a condition to test in for(;;). I
 confess that I was shocked when I found out that it was legal to have
 a for loop without a condition. That seems like doing while() or if(),
 which makes no sense. So, I never use for(;;) and wish that it didn't
 exist, but it does, and some folks use it. So, I have to live with the
 possiblity of dealing with it when dealing with code written by other
 people. But I won't ever use it.
IMO, it is very convenient for system programming guru. It is believed that it came from the K&R. For example, this option is definitely very convenient to use: https://github.com/dlang/phobos/blob/master/std/algorithm/comparison.d#L591
I like that function. If I were to review it now, I'd approve with these nits: * drop the parens for popFront * s/-cast(int)!r2.empty/-int(!r2.empty)/ * Merge with the cmp implementation for strings and simplify the constraint from if (isInputRange!R1 && isInputRange!R2 && !(isSomeString!R1 && isSomeString!R2)) to if (isInputRange!R1 && isInputRange!R2) i.e. it's not relevant to users that the string version has a distinct implementation. In fact I suggest someone implements this. Andrei
Nov 25 2016
next sibling parent Dennis Ritchie <dennis.ritchie mail.ru> writes:
On Friday, 25 November 2016 at 12:59:07 UTC, Andrei Alexandrescu 
wrote:
 i.e. it's not relevant to users that the string version has a 
 distinct implementation.

 In fact I suggest someone implements this.
The problem is not the users, and the places where you will use your program. Because this code is easy to make a mistake that can lead to failure in the automated system. Unfortunately, writing such code is not safe.
Nov 25 2016
prev sibling parent reply Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Friday, November 25, 2016 07:59:07 Andrei Alexandrescu via Digitalmars-d 
wrote:
 On 11/25/2016 07:53 AM, Dennis Ritchie wrote:
 https://github.com/dlang/phobos/blob/master/std/algorithm/comparison.d#L
 591
I like that function. If I were to review it now, I'd approve with these nits: * drop the parens for popFront
I would point out that technically, that breaks the range API. isInputRange requires that popFront be callable with parens, but it does not require that it be callable without parens. So, someone could define popFront as a public member variable with an overloaded opCall. That would not compile if it were used with code that called popFront without parens even though it would compile with isInputRange. Now, realistically, no one is going to do that, so it probably doesn't matter. But it seems to me that in general, when dealing with a trait like isInputRange which tests that a particular syntax is used, it's just safer to use that syntax rather than using parens where it doesn't or not using parens where it does. - Jonathan M Davis
Nov 25 2016
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 11/25/16 8:24 AM, Jonathan M Davis via Digitalmars-d wrote:
 I would point out that technically, that breaks the range API.
We need to change the range API then. -- Andrei
Nov 25 2016
next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Friday, 25 November 2016 at 15:03:26 UTC, Andrei Alexandrescu 
wrote:
 We need to change the range API then. -- Andrei
That's absurd, popFront is in no way semantically a property, so it should not get property. It has been so many years of this being poorly defined. Let's just close the book and officially put the status quo on optional parenthesis in stone: they are optional on zero-argument calls, regardless of property, and that isn't going to change. Then this popFront question becomes moot.
Nov 25 2016
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 11/25/16 10:29 AM, Adam D. Ruppe wrote:
 Let's just close the book and officially put the status quo on optional
 parenthesis in stone: they are optional on zero-argument calls,
 regardless of  property, and that isn't going to change.
Agreed. -- Andrei
Nov 25 2016
parent Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Friday, November 25, 2016 11:01:56 Andrei Alexandrescu via Digitalmars-d 
wrote:
 On 11/25/16 10:29 AM, Adam D. Ruppe wrote:
 Let's just close the book and officially put the status quo on optional
 parenthesis in stone: they are optional on zero-argument calls,
 regardless of  property, and that isn't going to change.
Agreed. -- Andrei
That's fine, but it doesn't help any when the callable can't be used with optional parens - which is the case with a type overloading opCall as well as function pointers and delegates. And the real problem here isn't whether someone chooses to call a function with parens or not in some chunk of their code. The problem is whether _generic_ code does it. If you're calling something with parens in generic code, then you need to be able to rely on it working with parens regardless of the types of the function arguments. And if you're calling it without parens, then you need to be able to rely on it working _without_ parens regardless of the types of the function arguments. Stuff like empty, save, and length in the range API all of the same problem as popFront and popBack except in reverse. In their case, they need to be called without parens, or the code won't work with some ranges (the most obvious case being for empty being infinite ranges, and the most obvious case for length being dynamic arrays). So, restricting popFront and popBack to being functions so that they can always be called without parens is fine, but it's still the case that you can't be completely lax with where you do or don't use parens in generic code. - Jonathan M Davis
Nov 25 2016
prev sibling parent reply Meta <jared771 gmail.com> writes:
On Friday, 25 November 2016 at 15:29:31 UTC, Adam D. Ruppe wrote:
 On Friday, 25 November 2016 at 15:03:26 UTC, Andrei 
 Alexandrescu wrote:
 We need to change the range API then. -- Andrei
That's absurd, popFront is in no way semantically a property, so it should not get property. It has been so many years of this being poorly defined. Let's just close the book and officially put the status quo on optional parenthesis in stone: they are optional on zero-argument calls, regardless of property, and that isn't going to change. Then this popFront question becomes moot.
This causes a world of pain when you want to pass functions around. Nothing gets my blood pressure up like the following code: https://forum.dlang.org/post/piktfrtpltmjvjmedspr forum.dlang.org
Dec 01 2016
parent Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Thursday, December 01, 2016 19:25:27 Meta via Digitalmars-d wrote:
 On Friday, 25 November 2016 at 15:29:31 UTC, Adam D. Ruppe wrote:
 On Friday, 25 November 2016 at 15:03:26 UTC, Andrei

 Alexandrescu wrote:
 We need to change the range API then. -- Andrei
That's absurd, popFront is in no way semantically a property, so it should not get property. It has been so many years of this being poorly defined. Let's just close the book and officially put the status quo on optional parenthesis in stone: they are optional on zero-argument calls, regardless of property, and that isn't going to change. Then this popFront question becomes moot.
This causes a world of pain when you want to pass functions around. Nothing gets my blood pressure up like the following code: https://forum.dlang.org/post/piktfrtpltmjvjmedspr forum.dlang.org
I think that having optional parens in D was a mistake, and your situation there is an example of why it can be a big problem (the problems caused by being lax with syntax in generic code is another). However, the shipped has long since sailed on that one. It's too popular and too widely used to change at this point. And while I completely agree that allowing optional parens causes problems, it's also true that a lot of code is able to use it without difficulties, and many folks like it, particularly when they have to use parens for template arguments in UFCS call chains. - Jonathan M Davis
Dec 01 2016
prev sibling parent Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Friday, November 25, 2016 10:03:26 Andrei Alexandrescu via Digitalmars-d 
wrote:
 On 11/25/16 8:24 AM, Jonathan M Davis via Digitalmars-d wrote:
 I would point out that technically, that breaks the range API.
We need to change the range API then. -- Andrei
We can certainly do that. I'm just pointing out that as it stands, it's legal to declare popFront to be a callable that doesn't work with optional parens, and as long as that's true, calling popFront without parens means that the code won't work with perfectly legitimate ranges. So, unless/until isInputRange is changed, I'd say that calling popFront without parens is a bad idea. - Jonathan M Davis
Nov 25 2016
prev sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 11/25/16 8:24 AM, Jonathan M Davis via Digitalmars-d wrote:
 On Friday, November 25, 2016 07:59:07 Andrei Alexandrescu via Digitalmars-d
 wrote:
 On 11/25/2016 07:53 AM, Dennis Ritchie wrote:
 https://github.com/dlang/phobos/blob/master/std/algorithm/comparison.d#L
 591
I like that function. If I were to review it now, I'd approve with these nits: * drop the parens for popFront
I would point out that technically, that breaks the range API. isInputRange requires that popFront be callable with parens, but it does not require that it be callable without parens. So, someone could define popFront as a public member variable with an overloaded opCall. That would not compile if it were used with code that called popFront without parens even though it would compile with isInputRange.
This is a misunderstanding. The missing parens is for *usage* of the range, not *definition* of the range. It won't affect isInputRange at all. This case you have of defining a popFront member variable with opCall -- don't do that, it will break things (I'm sure there are already many places where popFront is called without parens). I don't think that's a case that we need worry about. -Steve.
Nov 25 2016
next sibling parent reply Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Friday, November 25, 2016 10:46:15 Steven Schveighoffer via Digitalmars-d 
wrote:
 On 11/25/16 8:24 AM, Jonathan M Davis via Digitalmars-d wrote:
 On Friday, November 25, 2016 07:59:07 Andrei Alexandrescu via
 Digitalmars-d>
 wrote:
 On 11/25/2016 07:53 AM, Dennis Ritchie wrote:
 https://github.com/dlang/phobos/blob/master/std/algorithm/comparison.d
 #L
 591
I like that function. If I were to review it now, I'd approve with these nits: * drop the parens for popFront
I would point out that technically, that breaks the range API. isInputRange requires that popFront be callable with parens, but it does not require that it be callable without parens. So, someone could define popFront as a public member variable with an overloaded opCall. That would not compile if it were used with code that called popFront without parens even though it would compile with isInputRange.
This is a misunderstanding. The missing parens is for *usage* of the range, not *definition* of the range. It won't affect isInputRange at all.
It's not a misunderstanding. template isInputRange(R) { enum bool isInputRange = is(typeof( (inout int = 0) { R r = R.init; // can define a range object if (r.empty) {} // can test for empty r.popFront(); // can invoke popFront() auto h = r.front; // can get the front of the range })); } calls popFront with parens. That means that it's perfectly legal per isInputRange to define popFront such that it's a callable that does _not_ work with optional parens. So, if it were a member variable that defined opCall or was a delegate, then to use it, the parens are required. That means that I could define a range that passes isInputRange but does not work with code that called popFront without parens. As isInputRange is currently defined, it's perfectly legal.
 This case you have of defining a popFront member variable with opCall --
 don't do that, it will break things (I'm sure there are already many
 places where popFront is called without parens). I don't think that's a
 case that we need worry about.
It's a case that's currently legal. It's just not one that's particularly likely. We can certainly change isInputRange to make such a case illegal. But as it stands, someone could have defined such a range, and it would work with a _lot_ range-based code, because it's very common to call popFront with parens, and if such a range were being used with a function in Phobos, and that function were changed to call popFront without parens, it would break code. So, if we want to change the definition of isInputRange to get rid of this problem, fine. I'm just pointing out that as isInputRange is currently defined, calling popFront without parens would result in that code not working with ranges that are perfectly legal per isInputRange and could be perfectly legitimate ranges in all aspects of how they function. And calling empty _with_ parens even though it would be legal in most cases right now would have the exact same problem except in reverse. Everything wasn't a callable wouldn't work - including stuff like empty on infinite ranges. D allows us to be lax with syntax to some extent, but we need to be careful with how we deal with that in generic code, or we're going to end up with stuff that should work but doesn't just because parens happened to have been used or not in a particular piece of code. - Jonathan M Davis
Nov 25 2016
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 11/25/2016 11:47 AM, Jonathan M Davis via Digitalmars-d wrote:
 template isInputRange(R)
 {
     enum bool isInputRange = is(typeof(
     (inout int = 0)
     {
         R r = R.init;     // can define a range object
         if (r.empty) {}   // can test for empty
         r.popFront();     // can invoke popFront()
         auto h = r.front; // can get the front of the range
     }));
 }

 calls popFront with parens.
Jonathan, could you please make a PR to remove the parens. Thanks. -- Andrei
Nov 25 2016
parent Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Friday, November 25, 2016 11:51:24 Andrei Alexandrescu via Digitalmars-d 
wrote:
 Jonathan, could you please make a PR to remove the parens. Thanks.
Done. https://github.com/dlang/phobos/pull/4925 - Jonathan M Davis
Nov 25 2016
prev sibling parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 11/25/16 11:47 AM, Jonathan M Davis via Digitalmars-d wrote:
 On Friday, November 25, 2016 10:46:15 Steven Schveighoffer via Digitalmars-d
 wrote:
 On 11/25/16 8:24 AM, Jonathan M Davis via Digitalmars-d wrote:
 I would point out that technically, that breaks the range API.
 isInputRange requires that popFront be callable with parens, but it
 does not require that it be callable without parens. So, someone could
 define popFront as a public member variable with an overloaded opCall.
 That would not compile if it were used with code that called popFront
 without parens even though it would compile with isInputRange.
This is a misunderstanding. The missing parens is for *usage* of the range, not *definition* of the range. It won't affect isInputRange at all.
It's not a misunderstanding. template isInputRange(R) { enum bool isInputRange = is(typeof( (inout int = 0) { R r = R.init; // can define a range object if (r.empty) {} // can test for empty r.popFront(); // can invoke popFront() auto h = r.front; // can get the front of the range })); } calls popFront with parens. That means that it's perfectly legal per isInputRange to define popFront such that it's a callable that does _not_ work with optional parens. So, if it were a member variable that defined opCall or was a delegate, then to use it, the parens are required. That means that I could define a range that passes isInputRange but does not work with code that called popFront without parens. As isInputRange is currently defined, it's perfectly legal.
It's perfectly legal to make a popFront that destroys your entire program. Or that doesn't actually pop the front (see old generate() function). So what? I can't see the point of going out of your way to make a popFront member that supports opCall, when you can use a function. Note: there are cases out there where popFront is called without parentheses. It has never broken any code. This should be a hint that what you are concerned about doesn't happen in practice. -Steve
Nov 25 2016
prev sibling parent Kagamin <spam here.lot> writes:
On Friday, 25 November 2016 at 15:46:15 UTC, Steven Schveighoffer 
wrote:
 This case you have of defining a popFront member variable with 
 opCall -- don't do that, it will break things (I'm sure there 
 are already many places where popFront is called without 
 parens). I don't think that's a case that we need worry about.
Seems like not that many. grep -r "popFront;" * algorithm/comparison.d: r2.popFront; algorithm/comparison.d: r1.popFront; algorithm/comparison.d: r1.popFront; algorithm/comparison.d: r2.popFront; algorithm/mutation.d: void popFront() { data.popFront; } experimental/allocator/typed.d: front, popFront; experimental/ndslice/selection.d: val.popFront; experimental/ndslice/selection.d: elems2.popFront; experimental/ndslice/selection.d: elems2.popFront; experimental/ndslice/selection.d: elems.popFront; experimental/ndslice/slice.d: slice.popFront; experimental/ndslice/slice.d: slice.popFront; experimental/ndslice/slice.d: value.popFront; experimental/ndslice/slice.d: slice.popFront; experimental/ndslice/slice.d: value.popFront; experimental/ndslice/slice.d: slice.popFront; experimental/ndslice/slice.d: slice.popFront; experimental/ndslice/slice.d: slice.popFront; experimental/ndslice/slice.d: slice.popFront; experimental/ndslice/slice.d: slice.popFront; experimental/ndslice/slice.d: slice.popFront; range/package.d: return condition ? r1.popFront : r2.popFront; The last one is strange.
Nov 25 2016
prev sibling next sibling parent reply Claude <no no.no> writes:
On Friday, 25 November 2016 at 11:10:44 UTC, Timon Gehr wrote:
 On 25.11.2016 11:33, Claude wrote:
 ...

 Between "for(;;)", "while(true)" and "do while(true)", I would 
 use the
 "while (true) { }" for pure readability and semantic reasons.
 ...
What semantic reasons?
In the general sense: - While true (is always true), I loop. Is more meaningful and conceptually easy then the empty for statement : - For "empty initialization statement" until "I don't know (so forever by default)" and "not iterating", I loop.
 I reckon "for(;;)" form is used for debug reasons (so you can 
 easily
 insert conditions to transform an infinite loop into a finite 
 one).
You can just as easily edit the while condition. I use it because "unconditional loop" is less silly than "loop until true is false".
I was just trying to explain why one would use for(;;) instead of while(true), you've got only one line to edit. It's in same vein as using: if (cond) { }
Nov 25 2016
parent Claude <no no.no> writes:
Sorry, I sent my post before finishing it, so...

It's in same vein as using:

if (cond)
{
   singleStatement;
}

instead of:

if (cond)
   singleStatement;

Because, you can more easily insert statements within the block 
(without having to navigate to different to insert the brackets).
Nov 25 2016
prev sibling next sibling parent reply Kagamin <spam here.lot> writes:
On Friday, 25 November 2016 at 11:10:44 UTC, Timon Gehr wrote:
 You can just as easily edit the while condition. I use it 
 because "unconditional loop" is less silly than "loop until 
 true is false".
Unconditional loop can be implemented in 3 possible ways :) 1. skip it entirely: since there's no condition to check, can't decide if should enter at all 2. run once: since there's no condition to check, can't decide if should repeat - becomes just an unconditional block statement 3. infinite loop as if the condition is always true - until it's false
Nov 25 2016
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 25.11.2016 17:38, Kagamin wrote:
 On Friday, 25 November 2016 at 11:10:44 UTC, Timon Gehr wrote:
 You can just as easily edit the while condition. I use it because
 "unconditional loop" is less silly than "loop until true is false".
Unconditional loop can be implemented in 3 possible ways :) 1. skip it entirely: since there's no condition to check, can't decide if should enter at all 2. run once: since there's no condition to check, can't decide if should repeat - becomes just an unconditional block statement 3. infinite loop as if the condition is always true - until it's false
Grab a dictionary.
Nov 25 2016
prev sibling parent reply "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Fri, Nov 25, 2016 at 03:20:24AM -0800, Jonathan M Davis via Digitalmars-d
wrote:
 On Friday, November 25, 2016 12:10:44 Timon Gehr via Digitalmars-d wrote:
 On 25.11.2016 11:33, Claude wrote:
 ...

 Between "for(;;)", "while(true)" and "do while(true)", I would use the
 "while (true) { }" for pure readability and semantic reasons.
 ...
What semantic reasons?
Probably the complete lack of a condition to test in for(;;). I confess that I was shocked when I found out that it was legal to have a for loop without a condition. That seems like doing while() or if(), which makes no sense.
Sure it does. A conditionless loop is exactly what an infinite loop is. A while-loop, by definition, has a condition (loop *while* something is true, stop looping when it's no longer true), and an if-statement by definition is conditional. Neither match the nature of an infinite loop, which is infinite because it has no exit condition. Well, OK, a loop can also be infinite if the exit condition just happens to be always true, but I feel that is more deceptive than a conditionless loop when it's deliberately written, since a conditional loop whose condition happens to be always true sounds to me like a bug or a subversion (we intend this loop to stop when condition X becomes false, but bwahaha I arranged for X to never become false!). When a loop is *deliberately* meant to be infinite, I see a conditionless loop as a more faithful representation of that intent. Therefore I prefer `for(;;)` over any of the `while(true)`, `while(1)`, etc., variations. It conveys intent in a more straightforward, up-front way. If it helps you stomach it, you could interpret the `(;;)` as a funny way of saying "ever", so in essence you're saying `for-ever { ... }`. T -- Computers shouldn't beep through the keyhole.
Nov 25 2016
parent Dennis Ritchie <dennis.ritchie mail.ru> writes:
I don't mean an infinite loop for (;;), and violation of the 
concepts of structured programming, which put forward Dijkstra.

for (;;) {
     ...
     if (condition) {
         break;
     }
     ...
}

outer: for (;;) {
     ...
     if (condition) {
         goto outer;
     }
     ...
}

I.e. in system programming and I want to use `break` or `goto`, 
because here we use imperative rather than declarative approach.
The following question arises. Are structured programming concept 
of Dijkstra's right for writing system software?
Nov 25 2016
prev sibling parent reply Nick Sabalausky <SeeWebsiteToContactMe semitwist.com> writes:
On 11/24/2016 05:09 PM, Dennis Ritchie wrote:
 On Thursday, 24 November 2016 at 22:04:00 UTC, LiNbO3 wrote:
 As you can see [1] the `while (true)` is lowered into `for (;true;)`
 so it's all about what construct pleases you the most.

 [1]
 https://github.com/dlang/dmd/blob/cd451ceae40d04f7371e46df1c955fd914f3085f/src/statementsem.d#L357
OK, thanks. The next question is: What principles guided when choosing between `for (;;) { ... }` and `while (true) { ... }` ?
Personal preference. Nothing more. Programmers have far better things to do that fret over the relative merits of two identical constructs that have no relative (de)merits over each other.
Dec 01 2016
parent "H. S. Teoh via Digitalmars-d" <digitalmars-d puremagic.com> writes:
On Thu, Dec 01, 2016 at 11:23:26AM -0500, Nick Sabalausky via Digitalmars-d
wrote:
 On 11/24/2016 05:09 PM, Dennis Ritchie wrote:
[...]
 The next question is:
 What principles guided when choosing between `for (;;) { ... }` and
 `while (true) { ... }` ?
Personal preference. Nothing more. Programmers have far better things to do that fret over the relative merits of two identical constructs that have no relative (de)merits over each other.
Far better things? You mean, like having endless discussions about a controversial D topic on this forum while procrastinating on the actual writing of code? Yeah, I can see that. :-P T -- It is of the new things that men tire --- of fashions and proposals and improvements and change. It is the old things that startle and intoxicate. It is the old things that are young. -- G.K. Chesterton
Dec 01 2016
prev sibling parent reply unDEFER <undefer gmail.com> writes:
Why you consider only 2 options?
Use "do {} while (true);" :-)
Nov 24 2016
parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 25/11/2016 8:27 PM, unDEFER wrote:
 Why you consider only 2 options?
 Use "do {} while (true);" :-)
The condition only executes after a single iteration. So it is not the same code flow.
Nov 25 2016
parent Stefan Koch <uplink.coder googlemail.com> writes:
On Friday, 25 November 2016 at 08:46:24 UTC, rikki cattermole 
wrote:
 On 25/11/2016 8:27 PM, unDEFER wrote:
 Why you consider only 2 options?
 Use "do {} while (true);" :-)
The condition only executes after a single iteration. So it is not the same code flow.
For an the usecase infinite-loop the code has the same effect. And will translate to the same machine-code, hopefully.
Nov 25 2016