Path: 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 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. > 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