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.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,309015504ed37ff0 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2003-09-28 14:50:54 PST Path: news1.google.com!newsfeed.stanford.edu!headwall.stanford.edu!newshub.sdsu.edu!elnk-nf2-pas!newsfeed.earthlink.net!stamper.news.pas.earthlink.net!stamper.news.atl.earthlink.net!newsread2.news.atl.earthlink.net.POSTED!not-for-mail Sender: mheaney@MHEANEYX200 Newsgroups: comp.lang.ada Subject: Re: Usage of Interfaces with Ada 95 References: <1064595326.831730@master.nyc.kbcfp.com> <4nii41-067.ln1@boavista.snafu.de> From: Matthew Heaney Message-ID: User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.3 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Date: Sun, 28 Sep 2003 21:50:53 GMT NNTP-Posting-Host: 65.110.133.134 X-Complaints-To: abuse@earthlink.net X-Trace: newsread2.news.atl.earthlink.net 1064785853 65.110.133.134 (Sun, 28 Sep 2003 17:50:53 EDT) NNTP-Posting-Date: Sun, 28 Sep 2003 17:50:53 EDT Organization: EarthLink Inc. -- http://www.EarthLink.net Xref: news1.google.com comp.lang.ada:91 Date: 2003-09-28T21:50:53+00:00 List-Id: Michael Erdmann writes: > Again the iterator is nice example. For example if you take a group of > developers you will find an agreement that something like an iterator > is nessecary. But if you let them build there code independently, you > will find that all are using iterators on various but with slightly > different interfaces. I my example i like to provide a package > enumerator where the developer X can put in his data type, but the > gerneric package forces him to implement the interface for his data > type and nothing else. If the semantic of this interface is simple, it > will be mutch easier for somebody else to maintain the code written on > this concept. You still haven't groked the static polymorphism idea. If I have the following generic algorithm: generic type Iterator_Type is private; with function Succ (Iterator : Iterator_Type) return Iterator_Type is <>; with procedure Process (Iterator : Iterator_Type) is <>; with function "=" (L, R : Iterator_Type) return Boolean is <>; procedure Generic_Algorithm (First, Back : Iterator_Type); Then of course this is going to check how iterators are declared by independent developers -- as soon as he tries to instantiate the generic algorithm. Any iterator any developer builds must conform to this logical interface. You want the do the check at the time of compilation of the declaration of the iterator type. I don't. I defer the check until the time of compilation of the instantiation of the generic algorithm. If you understand the difference then you understand static polymorphism. Forget about Java because it's only going to confuse you. One consequence of defering the check is that is doesn't matter if independent developers come up with different iterator interfaces. The generic algorithm doesn't care, because it only cares about the logical properties of the iterator, not the syntax of the declaration. The algorithm above is written with Charles iterators in mind. So naturally it's simple to instantiate it. Let's start with a list: package List_Types is new Charles.Lists.Double.Unbounded (ET); procedure Op (List : List_Types.Container_Type) is procedure Process (I : List_Types.Iterator_Type) is E : ET := Element (I); begin ... -- do whatever end; procedure Algorithm is new Generic_Algorithm (Iterator_Type); -- accept defaults begin Algorithm (First (List), Back (List)); end; Now let's use the generic algorithm on a vector, which doesn't have an iterator type: package Vector_Types is new Charles.Vectors.Unbounded (Index_Typey => IT, Element_Type => ET); procedure Op (Vector : Vector_Type.Container_Type) is procedure Process (I : IT) is E : ET := Element (Vector, Index => I); begin ... -- do whatever end; procedure Algorithm is new Generic_Algorithm (Iterator_Type => IT, -- index subtype Succ => IT'Succ); begin Algorithm (First (Vector), Back (Vector)); end; Now let's use the generic algorithm again, on an array, which doesn't have an iterator type either: procedure Op (A : Array_Subtype) is procedure Process (I : IT) is E : ET renames A (I); begin ... -- do whatever end; procedure Algorithm is new Generic_Algorithm (Iterator_Type => IT, -- index subtype Succ => IT'Succ); begin Algorithm (First => A'First, Back => A'First + A'Length); end; In your original example, your preferred iterator style is to have operations First, Next, and HasMoreElement. Let's use the generic algorithm above on your iterator: procedure Op (C : in CT) is procedure Process (I : IT) is E : ET := Get_Element (I); -- or whatever begin ... -- do whatever end; function Is_Done (Iter, Back : IT) return Boolean is begin return not HasMoreElement (Iter); -- ignore Back end; procedure Algorithm is new Generic_Algorithm (Iterator_Type => IT, -- index subtype Succ => Next, "=" => Is_Done); Dummy : IT; begin -- Op Algorithm (First (C), Back => Dummy); end Op; So here you have 4 different containers, each with a different iteration scheme. Yet there is only a single generic algorithm. If you understand how this all works then you will understand static polymorphism. Forget about Java because it's only going to confuse you.