Recent

Author Topic: while loop with code before comparison  (Read 2082 times)

circular

  • Hero Member
  • *****
  • Posts: 3442
    • Personal webpage
Re: while loop with code before comparison
« Reply #15 on: August 11, 2020, 09:38:50 pm »
 :D that went well indeed.

I was imagining what I suggested in the first post, to have a for while construct. The iteration computation after for and the rest after while.

Though maybe there are more elegant ways to do that.
Conscience is the debugger of the mind

440bx

  • Hero Member
  • *****
  • Posts: 1994
Re: while loop with code before comparison
« Reply #16 on: August 11, 2020, 11:23:45 pm »
Suppose I want to display random numbers while they are less than some number. Such program can be written as:
Code: Pascal  [Select][+][-]
  1. var a: integer;
  2. begin
  3.   writeln('here are random percentages <= 75%');
  4.   randomize;
  5.   while true do
  6.   begin
  7.     a := random(101);
  8.     if a > 75 then break;
  9.     writeln(a, '%');
  10.   end;
  11. end.

This works, but I don't like the misleading "while true". The real condition is a <= 75. In C the solution to this is to used an assignment inside the condition, but I don't like it either.

- @Martin_fr: this solution seems to be actually the best, it works in all cases, no duplication of code. I would suggest an out parameter to avoid to have to initialize a.
Code: Pascal  [Select][+][-]
  1. function GetValue(out val: integer): boolean; inline;
  2. begin
  3.   val := random(101);
  4.   result := val <= 75; // test is defined here, that's no duplication
  5. end;
  6.  
  7. ......
  8.     var a: integer;
  9.     begin
  10.       writeln('here are random percentages <= 75%');
  11.       randomize;
  12.       while GetValue(a) do
  13.          writeln(a, '%');
  14.     end.
Just a "conversional" note.  You realize that Martin_fr's solution, which is elegant, is essentially exactly the same as the "while true do" loop which you are not fond of. 

Personally, I prefer the "while true do" solution because I don't have to go look for the function used in the "while" condition (it could be hundreds of lines away from the "while" statement - not common but bad source organization isn't  all that uncommon.)  I don't think "while true do" is misleading because, at least most of the time, the programmer would expect there is a condition being tested in the loop that will cause it to end (the cases where an infinite loop is useful are not very common.)


FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 6606
  • Debugger - SynEdit - and more
    • wiki
Re: while loop with code before comparison
« Reply #17 on: August 12, 2020, 01:42:00 am »
because I don't have to go look for the function used in the "while" condition (it could be hundreds of lines away from the "while" statement - not common but bad source organization isn't  all that uncommon.) 

<sarcasm>
Well, the ultimate solution is of course to have some classes and objects. There would have to be a TRandomProvider, TRangeChecker and most important a TProviderState.  The RangeChecker would update the state, and the provider could then decide what action to take by using the visitor pattern on the State.
Wrap that into an enumerator, and use a Mediator for the communication between enumerator and provider.
Just to keep it simple.
</sarcasm>
;)

circular

  • Hero Member
  • *****
  • Posts: 3442
    • Personal webpage
Re: while loop with code before comparison
« Reply #18 on: August 12, 2020, 07:19:41 am »
 :D
And have a class that contains the number as well, in case it is undefined. TNumber would have an IsLowerThanOrEqual function, that would return False when the number is undefined.

Just a "conversional" note.  You realize that Martin_fr's solution, which is elegant, is essentially exactly the same as the "while true do" loop which you are not fond of.
Nope, it doesn't suggest an infinite loop.

Quote
Personally, I prefer the "while true do" solution because I don't have to go look for the function used in the "while" condition (it could be hundreds of lines away from the "while" statement - not common but bad source organization isn't  all that uncommon.)
That's what I just said.

Quote
I don't think "while true do" is misleading because, at least most of the time, the programmer would expect there is a condition being tested in the loop that will cause it to end (the cases where an infinite loop is useful are not very common.)
Yeah, it is because we know that's a way to deal with certain cases to put an infinite loop.
Conscience is the debugger of the mind

440bx

  • Hero Member
  • *****
  • Posts: 1994
Re: while loop with code before comparison
« Reply #19 on: August 12, 2020, 08:00:48 am »
Nope, it doesn't suggest an infinite loop.
Anyone who reads that should have warning bells going off because there is a "mystery" function (until it is inspected) that may always return true.  Additionally, there is no indication whatsoever of what is the condition, if any, that will end the loop.

Yeah, it is because we know that's a way to deal with certain cases to put an infinite loop.
Seeing a statement "while true do" (should) immediately cause the programmer to search for the condition(s) that will end the loop and, if present, they must be in the loop (local.)

Martin_fr's solution is elegant but, it moves information into a different context (the function definition) which should be in the loop condition not someplace else.

At least when a programmer sees "while true do" he/she knows upfront it's an infinite loop.  In the other case, it may or may not be an infinite loop and the "decision" is made someplace else instead of in the "while".

The best/safest/clearest solution is the one you mentioned in your OP that you didn't like.
FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 8725
  • FPC developer.
Re: while loop with code before comparison
« Reply #20 on: August 12, 2020, 09:45:00 am »
Personally, I prefer the "while true do" solution because I don't have to go look for the function used in the "while" condition (it could be hundreds of lines away from the "while" statement - not common but bad source organization isn't  all that uncommon.)  I don't think "while true do" is misleading because, at least most of the time, the programmer would expect there is a condition being tested in the loop that will cause it to end (the cases where an infinite loop is useful are not very common.)

This is so wrong, and totally not like Wirth intended it.

Wirth intended to use the keyword LOOP which you luckily can add yourself with a bit of macro shenigans

Code: Pascal  [Select][+][-]
  1. {$mode delphi}
  2. {$macro on}
  3.  
  4. {$define loop:=while true do}
  5.  
  6. var i : integer;
  7. begin
  8.   LOOP
  9.   begin
  10.     i:=i+1;
  11.     if i>10 then
  12.       exit;
  13.     writeln(i);
  14.   end;
  15. end.

or another classic:
Code: Pascal  [Select][+][-]
  1. {$mode delphi}
  2.  
  3. const ENDOFTIME= false;
  4.        
  5.  begin
  6.   REPEAT
  7.   UNTIL ENDOFTIME;
  8. end.

p.s. this message is not 100% serious.
« Last Edit: August 12, 2020, 09:47:07 am by marcov »

circular

  • Hero Member
  • *****
  • Posts: 3442
    • Personal webpage
Re: while loop with code before comparison
« Reply #21 on: August 12, 2020, 09:51:39 am »
@440bx

I agree with the mystery problem, that's why it is not completely satisfying to have a function containing the comparison, in particular if there is a lot of code around.

I guess that @eny suggestions solves this:
Code: Pascal  [Select][+][-]
  1.   function AssignRandom(out n: integer): integer; inline;
  2.   begin
  3.     n := random(101);
  4.     exit(n)
  5.   end;
  6.  
  7. var
  8.   a: integer;
  9. begin
  10.   while AssignRandom(a) <= 75 do
  11.     writeln(a, '%');
  12. end;

In this case, there is no mystery on what AssignRandom does, and the test is in the condition.

I guess I like it as much as the infinite loop. Though somehow both are kind of tricks that tells me that a language structure is missing.

Similary, if we would use this new construct to do a basic for loop, that would not be satisfying:
Code: Pascal  [Select][+][-]
  1. var i: integer;
  2. begin
  3.   i := 0;
  4.   for inc(i) while i <= 10 do writeln(i);
  5. end;
Conscience is the debugger of the mind

440bx

  • Hero Member
  • *****
  • Posts: 1994
Re: while loop with code before comparison
« Reply #22 on: August 12, 2020, 10:12:04 am »
p.s. this message is not 100% serious.
Good :)  because macro shenanigans are not in my list of acceptable programming habits.



Though somehow both are kind of tricks that tells me that a language structure is missing.
The "solution" (note the quotes) or, I should say, the best known one, is to allow assignments within expressions.  That "solution", while at first seems like a good idea, it is Pandora's box (at least in C) because the immutability of the expression terms is neither guaranteed and, often not even obvious one way or the other.

Eny's suggestion is definitely good (that said, I don't see any reason to have "exit(n)" in there).  Actually, now that you've re-stated it, I think it is a better solution than the one presented by Martin_fr

In spite of that, I'd still go with the "while true do" because all the information a programmer needs is right there.  There is no need to look outside the "while" loop to figure out what controls it and how it is controlled.

IMO and experience, programs are much easier to understand and maintain when relationships among statements are grouped together.
FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

circular

  • Hero Member
  • *****
  • Posts: 3442
    • Personal webpage
Re: while loop with code before comparison
« Reply #23 on: August 12, 2020, 10:12:23 am »
@marcov

Oh no we had the conversation going nicely until now  :D

Using macros, sure is a way to solve the problem.  :D

Code: Pascal  [Select][+][-]
  1. {$MACRO ON}
  2. {$DEFINE foreach:=while true do begin}
  3. {$DEFINE where:=;if not (}
  4. {$DEFINE iterate:=) then break;}
  5. var a: integer;
  6. begin
  7.   writeln('here are random percentages <= 75%');
  8.   randomize;
  9.   foreach a := random(101) where a <= 75 iterate
  10.     writeln(a, '%');
  11.   end;
  12. end.
  13.  
Conscience is the debugger of the mind

circular

  • Hero Member
  • *****
  • Posts: 3442
    • Personal webpage
Re: while loop with code before comparison
« Reply #24 on: August 12, 2020, 10:15:02 am »
IMO and experience, programs are much easier to understand and maintain when relationships among statements are grouped together.
Hence the new language construct idea :)
Conscience is the debugger of the mind

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 6606
  • Debugger - SynEdit - and more
    • wiki
Re: while loop with code before comparison
« Reply #25 on: August 12, 2020, 10:20:42 am »
Still, the function can be far away if there is much code around, so I would still love a language construct for that.

Well, that would be solved by anonymous functions....

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 8725
  • FPC developer.
Re: while loop with code before comparison
« Reply #26 on: August 12, 2020, 10:21:29 am »
My point is actually that Wirth introduced such a construct (LOOP..END;) in Modula-2.

440bx

  • Hero Member
  • *****
  • Posts: 1994
Re: while loop with code before comparison
« Reply #27 on: August 12, 2020, 10:32:47 am »
My point is actually that Wirth introduced such a construct (LOOP..END;) in Modula-2.
Ok, does that mean you'd support the addition of a LOOP instruction in Free Pascal ? 
FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

circular

  • Hero Member
  • *****
  • Posts: 3442
    • Personal webpage
Re: while loop with code before comparison
« Reply #28 on: August 12, 2020, 11:35:33 am »
Well, that would be solved by anonymous functions....
Would it look like that?
Code: Pascal  [Select][+][-]
  1. var a: integer;
  2. begin
  3.   writeln('here are random percentages <= 75%');
  4.   randomize;
  5.   while function(out val: integer): boolean
  6.         begin
  7.           val := random(101);
  8.           result := val <= 75;
  9.         end (a) do
  10.      writeln(a, '%');
  11.   end;
  12. end.
That would not be readable.

My point is actually that Wirth introduced such a construct (LOOP..END;) in Modula-2.
Indeed. That would avoid the strange statement "while true" though that is still an infinite loop.
Conscience is the debugger of the mind

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 8725
  • FPC developer.
Re: while loop with code before comparison
« Reply #29 on: August 12, 2020, 12:16:08 pm »
My point is actually that Wirth introduced such a construct (LOOP..END;) in Modula-2.
Ok, does that mean you'd support the addition of a LOOP instruction in Free Pascal ?

I'd support the addition of a whole Modula2 mode to FPC. :)

 

TinyPortal © 2005-2018