comp.lang.ada
 help / color / mirror / Atom feed
From: eachus@spectre.mitre.org (Robert I. Eachus)
Subject: Re: How to Use Abstract Data Types
Date: 1998/04/30
Date: 1998-04-30T00:00:00+00:00	[thread overview]
Message-ID: <EACHUS.98Apr30161723@spectre.mitre.org> (raw)
In-Reply-To: 6hm556$95u$1@nnrp1.dejanews.com


In article <6hm556$95u$1@nnrp1.dejanews.com> adam@irvine.com writes:

 >  But it looks like this isn't going to work.  If I were to write a
 >  procedure that lists all the books in a library whose titles match,
 >  I'd want to be able to write:

 >      procedure List_Books_With_Matching_Titles
 >		     (Lib           : in Library'Class;
 >		      Title_Pattern : in String) is
 >	   ... declarations
 >      begin
 >	   Scan_By_Title (Lib, Title_Pattern, List_Scan, Error);
 >	   if Error then
 >	       Insult_The_User;
 >	       return;
 >	   end if;
 >	   while More_Books (List_Scan) loop
 >	       Next_Book (List_Scan, The_Book_To_List);
 >	       List_Book (The_Book_To_List);
 >	   end loop;
 >	   Close_Scan (List_Scan);
 >      end List_Books_With_Matching_Titles;

 >  But I don't see how this can be done, since I can't declare List_Scan.
 >  I can't declare it as Library_Package.Scan_Info since that is an
 >  abstract type...
-- Actually you can have non-abstract operations of abstract types,
-- but there is a better solution here.

 > Am I missing something trivial here?

-- Yes, but you can be forgiven because it is not trivial in many OO
-- langauges.  There are cases where you have to use access parameters
-- and all that to duplicate the normal way of doing iterators in
-- other languages.  In Ada, you are always better off making
-- iterators objects, but in Ada 95 the much cleaner way of doing
-- iterators is to use instances of generic packages as the iterator
-- objects.  Sounds compilicated, but it isn't.  First, we will
-- realize that Books and libraries are separate abstractions:

package Books is

   type Book is ...;
   function Title(B: Book) return String;
   ...
end Books;

with Books
package Libraries is

   type Library is abstract tagged null record;

   -- various abstract operations on Libraries.

   generic
      type Some_Library is new Library with private;
      This_Library: in out Some_Library;
   package Iterator is
      function More return Boolean;
      function Next return Book'Class;
   end Iterator;
 
private
   ...
end Libraries;
  

   The body of Iterator will call (abstract) primitives on Libraries.
Of course, when Iterator is instantiated, it will be on a non-abstract
class, so there will be actual code to call.  But that is not your
worry.

 > What is the cleanest way to accomplish what I'm trying to do?  This
 > looks like such a typical use of polymorphism that I'd be surprised if
 > there were no intuitive way to do it.

   Now to write your Scan_by_Title, lets make it a child of Libraries:

  generic
    type Some_Library is new Library with private;
  procedure Libraries.Scan_By_Title (Lib : in Some_Library;
                                 Reg_Expression : in String;
                                 Scan           : out Scan_Info;
                                 RE_Error       : out Boolean);

  procedure Libraries.Scan_By_Title (Lib : in Some_Library;
                                 Reg_Expression : in String;
                                 Scan           : out Scan_Info;
                                 RE_Error       : out Boolean) is
    ...
    package Local_Iterator is new Libraries.Iterator(Some_Library, Lib);
  begin
    ...
    while Local_Iterator.More loop
      Process_Book(Local_Iterator.Next, {other parameters});
    end loop;
  end Libraries.Scan_By_Title;

  I made this a child of Libraries for exposition purposes, you may
want to have Scan_By_Title as an abstract primitive of the Library
type and in effect, require that all non-abstract types derived from
Library provide a body, or you could make it a non-abstract primitive.
My leaning is to provide the Iterator as a child of Libraries, but to
provide the search function as an abstract primitive.  In other words,
some Library implementations may not have a concept of an ordering
among books, but might still provide a search mechanism.
  








--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




  parent reply	other threads:[~1998-04-30  0:00 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1998-04-22  0:00 How to Use Abstract Data Types adam
1998-04-23  0:00 ` Jacob Sparre Andersen
1998-04-30  0:00 ` Robert I. Eachus [this message]
     [not found]   ` <matthew_heaney-ya023680003004981709380001@news.ni.net>
1998-05-05  0:00     ` Stephen Leake
1998-05-05  0:00       ` Matthew Heaney
1998-05-06  0:00         ` Stephen Leake
  -- strict thread matches above, loose matches on Subject: below --
1998-04-30  0:00 adam
1998-05-06  0:00 ` Robert I. Eachus
1998-05-04  0:00 adam
1998-05-06  0:00 ` Robert I. Eachus
replies disabled

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