Recent

Author Topic: Feature suggestion - repeat while.. until  (Read 743 times)

egsuh

  • Hero Member
  • *****
  • Posts: 1800
Feature suggestion - repeat while.. until
« on: May 16, 2026, 01:04:28 pm »
How about this structure?


Code: Pascal  [Select][+][-]
  1. dataset.first;
  2. repeat while (not DataSet.eof)
  3.      // do something with the record..
  4.      dataset.next;
  5.      id := dataSet.Fields[0].AsInteger;
  6.  
  7. until id >= 10000;

The loop stops when the dataset reach end of dataset or a specific condition is met. Of course in this simple case the two conditions are easily combined, but sometimes there are very tricky situations.

cdbc

  • Hero Member
  • *****
  • Posts: 2814
    • http://www.cdbc.dk
Re: Feature suggestion - repeat while.. until
« Reply #1 on: May 16, 2026, 01:11:32 pm »
Hi
<long #¤%¤ sentence here> NOT!
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE6/QT6 -> FPC Release -> Lazarus Release &  FPC Main -> Lazarus Main

paweld

  • Hero Member
  • *****
  • Posts: 1639
Re: Feature suggestion - repeat while.. until
« Reply #2 on: May 16, 2026, 01:31:15 pm »
why not:
Code: Pascal  [Select][+][-]
  1.   dataset.first;
  2.   while not DataSet.eof do
  3.   begin
  4.     if dataSet.Fields[0].AsInteger >= 10000 then
  5.       break;
  6.     // do something with the record..
  7.     dataset.next;
  8.   end;
In my opinion, it's much simpler and clearer
Best regards / Pozdrawiam
paweld

cdbc

  • Hero Member
  • *****
  • Posts: 2814
    • http://www.cdbc.dk
Re: Feature suggestion - repeat while.. until
« Reply #3 on: May 16, 2026, 01:49:36 pm »
Hi
+1 to Pawel
@paweld: Exactly my thoughts; If one needs egsuh's proposal, one is clearly doing it wrong...!
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE6/QT6 -> FPC Release -> Lazarus Release &  FPC Main -> Lazarus Main

egsuh

  • Hero Member
  • *****
  • Posts: 1800
Re: Feature suggestion - repeat while.. until
« Reply #4 on: May 17, 2026, 06:32:25 am »
Quote
<long #¤%¤ sentence here> NOT!

What do you mean with this? If I'm bothering you in any way, I'll avoid it.

 
Code: Pascal  [Select][+][-]
  1.  dataset.first;
  2.   while not DataSet.eof do
  3.   begin
  4.     if dataSet.Fields[0].AsInteger >= 10000 then
  5.       break;
  6.     // do something with the record..
  7.     dataset.next;
  8.   end;

Yes, this is possible of course.  The key is not using break --- as if goto degrade readability.
I'll post more proper cases when I meet.

paweld

  • Hero Member
  • *****
  • Posts: 1639
Re: Feature suggestion - repeat while.. until
« Reply #5 on: May 17, 2026, 07:38:10 am »
I don't agree that break reduces readability - it's important to remember that it simply breaks the current loop. Unlike goto, which jumps to a specific location (label).
And if you don't want to use break, you can also extend the condition for while:
Code: Pascal  [Select][+][-]
  1.   dataset.first;
  2.   while not DataSet.eof and (dataSet.Fields[0].AsInteger < 10000) {or: `not (dataSet.Fields[0].AsInteger >= 10000)` } do
  3.   begin
  4.     // do something with the record..
  5.     dataset.next;
  6.   end;
Best regards / Pozdrawiam
paweld

Khrys

  • Sr. Member
  • ****
  • Posts: 456
Re: Feature suggestion - repeat while.. until
« Reply #6 on: May 18, 2026, 07:14:31 am »
The key is not using break --- as if goto degrade readability.

Splitting the loop condition in half does more to degrade readability than a single goto ever would, IMHO.

Of course in this simple case the two conditions are easily combined, but sometimes there are very tricky situations.

What would such a situation be? I've never felt the need for such a construct,  while  with boolean short-circuiting (as @paweld demonstrated) is already powerful enough.

Zvoni

  • Hero Member
  • *****
  • Posts: 3398
Re: Feature suggestion - repeat while.. until
« Reply #7 on: May 18, 2026, 08:45:09 am »
why not:
Code: Pascal  [Select][+][-]
  1.   dataset.first;
  2.   while not DataSet.eof do
  3.   begin
  4.     if dataSet.Fields[0].AsInteger >= 10000 then
  5.       break;
  6.     // do something with the record..
  7.     dataset.next;
  8.   end;
In my opinion, it's much simpler and clearer

A bit of nitpicking: pawel's code (and all other following it) is NOT equivalent to OP's sample

Correct:
Code: Pascal  [Select][+][-]
  1.   dataset.first;
  2.   while not DataSet.eof do
  3.   begin
  4. // do something with the record..
  5.     dataset.next;
  6.     if dataSet.Fields[0].AsInteger >= 10000 then break; //Condition-Check is the last Statement in a repeat-loop
  7.   end;
« Last Edit: May 18, 2026, 08:46:43 am by Zvoni »
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

Warfley

  • Hero Member
  • *****
  • Posts: 2066
Re: Feature suggestion - repeat while.. until
« Reply #8 on: May 18, 2026, 09:50:41 am »
The difference between a head condition vs a tail condition in a loop is only the very first check. So if the goal is to have both withouth a break, the easiest solution would be:
Code: Pascal  [Select][+][-]
  1. dataset.first;
  2. if not DataSet.eof then
  3.   repeat
  4.     ...
  5.   until DataSet.eof or (dataSet.Fields[0].AsInteger >= 10000);

ASerge

  • Hero Member
  • *****
  • Posts: 2497
Re: Feature suggestion - repeat while.. until
« Reply #9 on: May 18, 2026, 09:15:26 pm »
A bit of nitpicking: pawel's code (and all other following it) is NOT equivalent to OP's sample
I think the OP code contains an error, but the suggested code is more correct.
Error: skipping the first record and doing something after eof.

DavidL

  • New Member
  • *
  • Posts: 20
Re: Feature suggestion - repeat while.. until
« Reply #10 on: May 19, 2026, 03:14:55 pm »
The difference between a head condition vs a tail condition in a loop is only the very first check. So if the goal is to have both withouth a break, the easiest solution would be:
Code: Pascal  [Select][+][-]
  1. dataset.first;
  2. if not DataSet.eof then
  3.   repeat
  4.     ...
  5.   until DataSet.eof or (dataSet.Fields[0].AsInteger >= 10000);

This is correct only with short-circuit evaluation of the OR, yes?

Thaddy

  • Hero Member
  • *****
  • Posts: 19262
  • Glad to be alive.
Re: Feature suggestion - repeat while.. until
« Reply #11 on: May 19, 2026, 03:17:46 pm »
@DavidL
No. Shortcut stops when the first is true. It won't and does not need to evaluate the second condition.
Because you asked for OR.
The second condition is only evaluated if the first is false.
Without shortcut evaluation both are evaluated, but the result is always the same.

Leaving shortcut evaluation OFF is only relevant if you want to evaluate OR booleans in constant time.
Because constant time is the only side effect, except from some rare, contrived, conditions that change variables during evaluation and rely on that: bad code.
Constant time is only necessary to counter timing attacks.

What does matter is having the most common condition evaluate first: faster code.
In this case: if you know the dataset is - or can be - larger than 10000, reverse the conditions.
« Last Edit: May 19, 2026, 04:02:01 pm by Thaddy »
objects are fine constructs. You can even initialize them with constructors.

rvk

  • Hero Member
  • *****
  • Posts: 7045
Re: Feature suggestion - repeat while.. until
« Reply #12 on: May 19, 2026, 03:49:42 pm »
How about this structure?
Code: Pascal  [Select][+][-]
  1. dataset.first;
  2. repeat while (not DataSet.eof)
  3.      // do something with the record..
  4.      dataset.next;
  5.      id := dataSet.Fields[0].AsInteger;
  6.  
  7. until id >= 10000;

The loop stops when the dataset reach end of dataset or a specific condition is met. Of course in this simple case the two conditions are easily combined, but sometimes there are very tricky situations.
Maybe you should specify that "very tricky" situation then.

In your example you can end up with id < 10000 and no more records (dataset.eof). What then ???
(mixing while and repeat would only make code less readable)

The difference between a head condition vs a tail condition in a loop is only the very first check. So if the goal is to have both withouth a break, the easiest solution would be:
Code: Pascal  [Select][+][-]
  1. dataset.first;
  2. if not DataSet.eof then
  3.   repeat
  4.     ...
  5.   until DataSet.eof or (dataSet.Fields[0].AsInteger >= 10000);
If you do this you (can) miss the processing of the last record (assuming you do dataset.next just before the until (because if you don't, you miss processing the first record).
« Last Edit: May 19, 2026, 04:10:29 pm by rvk »

Zvoni

  • Hero Member
  • *****
  • Posts: 3398
Re: Feature suggestion - repeat while.. until
« Reply #13 on: May 19, 2026, 04:00:29 pm »
The difference between a head condition vs a tail condition in a loop is only the very first check. So if the goal is to have both withouth a break, the easiest solution would be:
Code: Pascal  [Select][+][-]
  1. dataset.first;
  2. if not DataSet.eof then
  3.   repeat
  4.     ...
  5.   until DataSet.eof or (dataSet.Fields[0].AsInteger >= 10000);
If you do this you miss the processing of the last record (assuming you do dataset.next just before the until (because if you don't, you miss processing the first record).
Correct. Spotted it, too, while looking at it again.
On (Re-)"Entrance" of the loop, let's say you're on ID=9999
You process your record
You reach the "dataset.next" which is last line before "until..."
dataset.eof is still false, because you actually have a dataset with exactly 10K records
Your ID is now 10.000 and satisfies the second exit-condition.

Record with ID=10000 will not be processed

https://www.freepascal.org/docs-html/fcl/db/tdataset.eof.html
Quote
Note: when the cursor is on the last-but-one record, and Next is called (moving the cursor to the last record), EOF will not yet be True. Only if both the cursor is on the last record and Next is called, will EOF become True.
« Last Edit: May 19, 2026, 04:10:08 pm by Zvoni »
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

Khrys

  • Sr. Member
  • ****
  • Posts: 456
Re: Feature suggestion - repeat while.. until
« Reply #14 on: May 19, 2026, 04:02:54 pm »
The difference between a head condition vs a tail condition in a loop is only the very first check. So if the goal is to have both withouth a break, the easiest solution would be:
Code: Pascal  [Select][+][-]
  1. dataset.first;
  2. if not DataSet.eof then
  3.   repeat
  4.     ...
  5.   until DataSet.eof or (dataSet.Fields[0].AsInteger >= 10000);

This is correct only with short-circuit evaluation of the OR, yes?

Indeed. When  {$B+}  is on for some reason (full boolean evaluation), the field access will raise an exception once EOF is reached.

Edit: As @rvk pointed out,  TDataSet.Fields  still points to the last available record once EOF is reached, so no exception will be raised and the code just so happens to work.
« Last Edit: May 20, 2026, 07:15:03 am by Khrys »

 

TinyPortal © 2005-2018