🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.lang.misc
Article #5380

Re: Iterators

#5380
From: Erland Sommarskog
Date: Fri, 25 Mar 1988 09:27
78 lines
3607 bytes
Stephen Crawley (scc@cl.cam.ac.uk) writes:
>2)  Declare the loop body procedure in the same (non-global) scope as
>    the local variables for the loop.  The loop locals are then available
>    to the loop body procedure as non-locals.  This assumes that your
>    language allows this ... C, BCPL, Pascal, Modula-*, Ada etc don't, 
>    but Algol-68 and Mesa do, as do any languages which support proper
>    procedure closures.
> <Example deleted for brevity>

I'm not entirely sure what you mean, so my apologies if my objection
isn't relevant. But looking at your example, it seems something that
is straghtforward to do in Ada. I even did it not long ago. And since
everyone is posting their favourite C iterators, you get some outlines
of it in Ada too.

First I have a generic package for binary trees. The package includes
generic procedures for traversing the tree in different directions.
This looks like:

   Generic
      Type Data_type is limited private;
      With procedure Assign(A : in out Data_type;
                            B : in     Data_type);
      With function "<"(A, B : Data_type) return boolean is <>;
      With function ">"(A, B : Data_type) return boolean is <>;
   -- We need the assignment and relations since we don't know anything   
   -- about what the user want to strore in the tree.
   Package binary_trees is
      Type Tree_type is private;     
      Type Node_type is private;     
      Null_node : constant Node_type; 
   ....      
      Generic
         With Procedure Treat(Node : in     Node_type;  
                              Data : in out Data_type); 
      Procedure Traverse_forward(Tree : Tree_type);
   ....
   End Binary_trees;
   
When I want to traverse the tree, I just instantiate the traversion 
procedure with a local one:

   Package Tree_handler is new Binary_trees(Data_ref); Use Tree_handler;
   ...
   Function Find_node(Criterion : Some_type) return Node_type is
   -- Traverses the (globally declared) tree and returns the first
   -- node that matches the criterion.
   Begin                 
      Declare
         Sought_node : Node_type;
         Found       : exception;
         Procedure Check_this_one(Node : in     Node_type;
                                  Data : in out Data_ref) is
         Begin                     
            If Data.Test_item = Criterion then
               Sought_node := Node;
               Raise Found;
            End if;
         End Check_this_one;
         Procedure Search is new Traverse_forward(Check_this_one); 
      Begin
         Search(Global_tree);
      Exception
         when found => Return Sought_node;
      End;
   End Find_node;

Now, isn't this very similar to the example Stephen posted?
(There are probably some people objecting strongly against the use
of the exception here. And I may well agree it's brute force. 
I included it just to show that there is a way out, ever the author 
of the iterator forgot to put in a stop condition.)  

-- 
Erland Sommarskog       
ENEA Data, Stockholm        
sommar@enea.UUCP           "Si tu crois l'amour tabou...
                            Regarde bien, les yeux d'un fou!!!" -- Ange
Technical Details
Message-ID: <2913@enea.se>
Path: arc1-ca.pugleaf.net!utzoo!mnetor!uunet!mcvax!enea!sommar
References: <1147@jenny.cl.cam.ac.uk>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!mnetor!uunet!mcvax!enea!sommar
From: sommar@enea.se (Erland Sommarskog)
Newsgroups: comp.lang.misc
Subject: Re: Iterators
Message-ID: <2913@enea.se>
Date: 25 Mar 88 09:27:25 GMT
References: <1147@jenny.cl.cam.ac.uk>
Reply-To: sommar@enea.UUCP(Erland Sommarskog)
Followup-To: comp.lang.misc
Organization: ENEA DATA AB, Sweden
Lines: 78