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,6b85f5fd782a1527 X-Google-Attributes: gid103376,public From: eachus@spectre.mitre.org (Robert I. Eachus) Subject: Re: How to Use Abstract Data Types Date: 1998/04/30 Message-ID: #1/1 X-Deja-AN: 349231155 References: <6hm556$95u$1@nnrp1.dejanews.com> Organization: The Mitre Corp., Bedford, MA. Newsgroups: comp.lang.ada Date: 1998-04-30T00:00:00+00:00 List-Id: 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...