Watch, Follow, &
Connect with Us

Please visit our new home
community.embarcadero.com.

Public Report
Report From: Delphi-BCB/Compiler/Delphi/Language    [ Add a report in this area ]  
Report #:  4815   Status: Closed
Iterators (like in the programming language CLU)
Project:  Delphi Build #:  ?
Version:    7.0 Submitted By:   Jasper Neumann
Report Type:  New Feature Request Date Reported:  6/23/2003 6:58:13 AM
Severity:    Commonly encountered problem Last Updated: 12/12/2004 4:27:16 AM
Platform:    All platforms Internal Tracking #:  
Resolution: Fixed (Resolution Comments) Resolved in Build: : 9.0.1761.24408
Duplicate of:  None
Voting and Rating
Overall Rating: (3 Total Ratings)
1.33 out of 5
Total Votes: None
Description
Motivation:
Delegation of extensive loop constructions as one procedure call. One should not be forced to repeat them again and again.
The traditional way (e.g. C++ STL) uses an object with up to 6 methods (create, init, eof, value, step, free); in contrast to this with CLU-iterators you cannot run two iterators simultaneously (in one thread) to e.g. compare two lists but it is much easier, and by the way no space on the heap is necessary.
By the way: In qgrids.pas the method TSparsePointerArray.ForAll and in TVision's TCollection.ForEach and TCollection.FirstThat such iterators were already simulated...

Application:
Loop through containers (lists, trees, parameters, directories, registry, etc.). "frame routines", e.g. for locking purposes.

Semantic:
Principely the iterator is called, which on its part calls the loop body on each yield.
The loop body and its scope (principly a local procedure) are transferred as hidden parameters.The iterator communicates with the loop body via reference parameters.

Simple example (result: '1 2 3 4 7 8 9 10 ')

type
  tn_set=byte;
  tsn_set=set of tn_set;

iterator for_in(var i:byte; const s:tsn_set);
var
  j: tn_set;
  ss: tsn_set;
begin
  ss:=s;  (* Local copy, might be necessary or implicitely supplied *)
  for j:=0 to 255 do begin
    if j in ss then begin
      i:=j;
      YIELD(iterator_base);
    end;
  end;
end;

var
  q: tn_set;
begin
  for_in(q, [1..3, 7..10]) do begin
    write(q,' ');
  end;
end.

References:
http://www.home.unix-ag.org/tjabo/ruby/uguide/uguide08.html
http://webster.cs.ucr.edu/Page_asm/ArtofAssembly/ch12/CH12-6.html
Steps to Reproduce:
None
Workarounds
I have supplied a facility to simulate these iterators.
Should work with Borland Pascal version 4 and up, too!
Have fun...
Attachment
SIM_ITER.ZIP
Comments

Brian Cook at 6/23/2003 10:57:40 PM -
What's a "CLU"?

Jasper Neumann at 6/23/2003 11:43:35 PM -
CLU is a programming language, see references.

Kristofer Skaug at 12/10/2004 2:44:58 AM -
Does D2005's new for..in..do language construct answer your request?

Jasper Neumann at 3/24/2005 3:39:16 AM -
The for..in construct is effectively only "syntactic sugar" based around a while loop.
Of course looping through an array, a set, a list or similar can be easily realized via the for..in construct or using a decorated while loop, but with CLU iterators you can for instance easily step through a tree using recursion.
When you try to simulate that, you will have to maintain a stack or similar.
In many occasions you can replace a method pointer parameter with a CLU iterator call where the method call or the method itself is placed in the iterator loop body - all local variables are visible there, so there is no need to copy them temporarily to the object and afterwards back.
There are many applications where a CLU iterator is the method of choice...

Deborah Pate at 12/12/2004 4:28:29 AM -
I've decided that it does, since it handles his specific example of a constant set.

Jasper Neumann at 2/28/2006 2:10:12 AM -
"Fixed" is the wrong answer since nothing is fixed.
I provided the specific example for demonstration purposes and I find it is not fair to say the request is fixed simply because the example is too simple.

CLU iterators are often not replaceable by for..in whereas vice versa always succeeds.
Moreover you can only have one iterator per container whereas CLU iterators can exist without any containers and you can have as many as you like, e.g.:
- step a tree forward
- step a tree backward
- step a tree prefix forward
- step a tree prefix backward
- step a tree postfix forward
- step a tree postfix backward
- step a tree tier wise forward
- step a tree tier wise backward
- step a tree tier skipping every second element
or completely other stuff such as
- creating power loops
- synchronizing to the main thread

In effect you can do whatever you can do with a procedure or method callback function with the added benefit that the scope of the calling place is completely transferred and you can write this proc in-place.

Server Response from: ETNACODE01