Article View: comp.lang.misc
Article #5353Iterators (was Re: From Modula to Oberon)
From: Stephen Crawley
Date: Fri, 18 Mar 1988 19:36
Date: Fri, 18 Mar 1988 19:36
76 lines
3077 bytes
3077 bytes
In article <1139@PT.CS.CMU.EDU> edw@IUS1.CS.CMU.EDU (Eddie Wyatt) writes:
In an earlier article, someone else writes:
>> [... Clu iterators are coroutines]
No they are not. Most of the things that you can do with coroutines you
can't do with iterators.
>But do you need coroutines to implimented generlized iteration.
>I think not.
Spot on. You CAN implement iterators with coroutines, but in practice
they are implemented more cheaply by turning the loop body into a procedure
like thing that is passed to the iterator as a hidden parameter. More
details on the implementation of CLU iterators can be found in
DGS Note 124 "VAX CLU Implementation Notes" by Sharon E. Perl 29/11/84
Laboratory for Computer Science, Massachusetts Institute of Technology
> [...]
>Example:
>
> void iterate_inorder(root,func)
> TREE *root;
> void (*func)();
> {
> if (root != NULLPTR(TREE))
> {
> iterate_inorder(root->left,func);
> func(root->val);
> iterate_inorder(root->right,func);
> }
> }
>
> I do see one problem though, which is dealing with variable
> referenced inside the loop. They would have to become
> global. Comments as to why this method might not work in general?
Apart from being a disgusting hack ... making your "local" variables into
globals will only work if the pseudo-iterator is NEVER called recursively.
To get it to work recursively, there are two approaches.
1) Declare the relevant local variables as a structure, and pass a
pointer to the struct as an extra parameter to the iter procedure
and hence to the "loop body" procedure. This involves casting /
loopholing of the pointer, or a generic type parameter in a high
level programming language.
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.
Here's an example of 2)
...
P: proc (...) =
x, y: FooType
loopbody: proc (elem: ElemType) = {
...
x := list_elem.foo
list_elem.foo := y
...
}
(* body of P *)
...
iterate_over(list, loopbody)
...
}
-- Steve
Technical Details
Message-ID:
<1147@jenny.cl.cam.ac.uk>Path:
arc1-ca.pugleaf.net!utzoo!mnetor!uunet!mcvax!ukc!cam-cl!sccReferences:
<2827@enea.se> <1557@pasteur.Berkeley.Edu> <3764@bloom-beacon.MIT.EDU> <22162@bbn.COM> <1139@PT.CS.CMU.EDU>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!mnetor!uunet!mcvax!ukc!cam-cl!scc From: scc@cl.cam.ac.uk (Stephen Crawley) Newsgroups: comp.lang.misc Subject: Iterators (was Re: From Modula to Oberon) Message-ID: <1147@jenny.cl.cam.ac.uk> Date: 18 Mar 88 19:36:35 GMT References: <2827@enea.se> <1557@pasteur.Berkeley.Edu> <3764@bloom-beacon.MIT.EDU> <22162@bbn.COM> <1139@PT.CS.CMU.EDU> Sender: scc@cl.cam.ac.uk Reply-To: scc@cl.cam.ac.uk (Stephen Crawley) Organization: U of Cambridge Comp Lab, UK Lines: 76 Keywords: CLU iterators closures genericity Summary: You CAN simulate iterators ... but it is not nice