From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.3 required=5.0 tests=BAYES_00,INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,5d0ce0dbca0a2038 X-Google-Attributes: gid103376,public From: mheaney@ni.net (Matthew Heaney) Subject: Re: Q: Primitive operation of a type Date: 1997/07/14 Message-ID: #1/1 X-Deja-AN: 256804084 References: <5oq51h$t7u@netline.jpl.nasa.gov> <33BA43CC.E27C69CC@elca-matrix.ch> <33C24D61.86746FC7@elca-matrix.ch> Organization: Estormza Software Newsgroups: comp.lang.ada Date: 1997-07-14T00:00:00+00:00 List-Id: In article <33C24D61.86746FC7@elca-matrix.ch>, Mats.Weber@elca-matrix.ch wrote: >How about an iterator that is just a procedure ? That way, the iterator is >part of the primitive profile of the type and gets inherited (and I'll have to >convert all my Ada 83 iterator specifications based on generics :-(). Yes, it's very desirable to make the iteration a primitive operation somehow, because that admits overriding the operation for the derived type. However, the procedure solution seems to be fighting the language. Note 85 in RM95 3.10.2 (37) specifically states that "The accessibility rules imply that is is not possible to use the Access attribute to ... pass a more-nested subprogram as a parameter to a less-nested subprogram, as might be desired for example for an iterator abstraction." So you might not want to convert your Ada 83 generic iterators, because the next sentance says "Instead, downward closures can be implemented using generic formal subprograms." Of course, if you're using GNAT, you can do what you want by using the Unrestricted_Access attribute (I think). If a passive form of iterator is more efficient, then can't we combine the best of both techniques? generic type Set_Item is private; package Sets_G is type Root_Set is abstract tagged private; type Root_Set_Iterator is abstract tagged private; procedure Iterate (Set : in Root_Set; Iterator : in out Root_Set_Iterator'Class) is abstract; procedure Process (Item : in Set_Item; Iterator : in Root_Set_Iterator) is abstract; end; generic package Sets_G.AVL_G is type AVL_Set is new Root_Set with private; procedure Iterate (Set : in AVL_Set; Iterator : in out Root_Set_Iterator'Class); ... end; package body Sets_G.AVL_G is procedure Iterate (Set : in AVL_Set; Iterator : in out Root_Set_Iterator'Class) is end Iterate; end; One issue with this solution is that it would be nice to write a generic package to do some class-wide operations, but that would require derivation inside a generic package, with isn't allowed (I think): generic with function Image (Item : Set_Item) return String; package Sets_G.Text_IO_G is procedure Put (Set : in Root_Set'Class); end; package body Sets_G.Text_IO_G is type Put_Iterator is new Root_Set_Iterator with null record; procedure Process (Item : in Set_Item; Iterator : in out Put_Iterator) is begin Ada.Text_IO.Put (Image (Item)); end Process; procedure Put (Set : in Root_Set'Class) is Iterator : Put_Iterator; begin Iterate (Set, Iterator); end; end; Sadly, I don't think this will work, because Sets_G.Text_IO_G is a generic package. The solution you suggested will would work in this particular case, because no local data is required to implement Put, so a library level callback can be passed to the iterate operation. However, in practice, many abstractions that use iteration require data local to the subprogram, so a callback can't be used (portably). So I'm at a bit of an impass. If you really want passive iteration, then you have to use a non-portable attribute. Or else you can use active iteration, but at a cost of some loss of efficiency. Even with the active-iterator-as-separate-type technique, I haven't come with any good solutions to iterate over a class-wide object. Perhaps I can just simplify my life by using a cursor-based solution; simultaneous iteration over the same data structure isn't that common, in my experience. Oh well. If anyone has any brilliant ideas about iteration (active or passive) over a class-wide object, please post them! Matt -------------------------------------------------------------------- Matthew Heaney Software Development Consultant (818) 985-1271