comp.lang.ada
 help / color / mirror / Atom feed
From: mheaney@ni.net (Matthew Heaney)
Subject: Re: Q: Primitive operation of a type
Date: 1997/07/14
Date: 1997-07-14T00:00:00+00:00	[thread overview]
Message-ID: <mheaney-ya023680001407970230090001@news.ni.net> (raw)
In-Reply-To: 33C24D61.86746FC7@elca-matrix.ch


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
   
      <call Process (Item, Iterator) for each item in the avl tree>

   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
<mailto:matthew_heaney@acm.org>
(818) 985-1271




  reply	other threads:[~1997-07-14  0:00 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1997-06-25  0:00 Q: Primitive operation of a type Van Snyder
1997-07-01  0:00 ` Matthew Heaney
1997-07-02  0:00   ` Mats Weber
1997-07-03  0:00     ` Matthew Heaney
1997-07-08  0:00       ` Mats Weber
1997-07-14  0:00         ` Matthew Heaney [this message]
1997-07-02  0:00 ` Martin C. Carlisle
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox