Path: utzoo!censor!geac!torsqnt!news-server.csri.toronto.edu!cs.utexas.edu!wuarchive!uunet!mcsun!ukc!pyrltd!tetrauk!rick From: rick@tetrauk.UUCP (Rick Jones) Newsgroups: comp.object Subject: Re: Re-use and functions as data (Was: Examples of Multiple Inheritance) Keywords: OOP, Reuse and languages with functions as first class objects Message-ID: <1063@tetrauk.UUCP> Date: 19 Dec 90 17:06:22 GMT References: <60700005@inmet> <980@culhua.prg.ox.ac.uk> <17562@neptune.inf.ethz.ch> <743@puck.mrcu> <1056@tetrauk.UUCP> <4040@syma.sussex.ac.uk> Reply-To: rick@tetrauk.UUCP (Rick Jones) Organization: Tetra Ltd., Maidenhead, UK Lines: 131 In article <4040@syma.sussex.ac.uk> aarons@syma.sussex.ac.uk (Aaron Sloman) writes: >[ ... ] Some >(though probably not all) of the facilitation of re-use that comes >from OO Languages can also be achieved by languages that allow >procedures to create functions and return them as results that can >be used as input to other procedures that call them [ ...] >A toy example, to illustrate: suppose you want to have a re-usable >function -create_pairs- that takes in two lists of objects (of any >type), a function that creates two-element records, with one object >from each list, and then makes and returns a sorted list of the two >element records, where the required ordering of the sorted list >depends on the types of objects in the list, etc. >(How would you do this in an OO Language?). OK, you issued the challenge :-) In Eiffel you would rely heavily on generic classes. First, a class to define a PAIR object (note - I've deliberately squashed normal Eiffel layout so as not to spread this article out too much): deferred class PAIR [T, U] export repeat COMPARABLE, item1, item2 inherit COMPARABLE redefine infix "<" feature item1: T; item2: U; infix "<" (other: like Current) is deferred end; end This defines the abstraction of a pair - i.e. it has two members, item1 & item2, whose types are generic, and is a COMPARABLE type, where the actual comparison operation is to be defined in a descendant class. (COMPARABLE is a library class which provides all the other comparison operators as derivatives of "<", so only that one has to receive a definition.) Now for the sorted list of pairs. Here we use an existing generic library class SORTED_LIST to create a deferred (abstract) class containing sorted pairs: deferred class SORTED_PAIRS [T, U] export repeat SORTED_LIST inherit SORTED_LIST [PAIR [T, U]] feature build (list1: LIST [T], list2: LIST [U]) is -- builds pairs into this list from two lists -- of relevant items do from list1.start; list2.start; until list1.off or list2.off loop -- this inherited routine puts the item at the -- correct place put (new_pair (list1.item, list2.item)); end; end ; -- deferred routine to create new pair objects new_pair (p1: T, p2: U): PAIR [T, U] is deferred end; end We then create non-deferred classes inheriting from the above to handle a specific type of pair. Some actual pair class would be like: class MY_PAIR export repeat PAIR inherit PAIR [INTEGER, STRING] define infix "<" feature Create (i: INTEGER, s: STRING) is do item1 := i; item2 := s; end; infix "<" (other: like Current) is do Result := item1 < other.item1; end; end This is an integer/string pair, where the comparison is done on the integer value. The sorted list of these pairs would be: class SORT_MY_PAIR is export repeat SORTED_PAIRS inherit SORTED_PAIRS [INTEGER, STRING] define new_pair feature Create (ints: LIST [INTEGER], strs: LIST [STRING]) is do build (ints, strs); end; new_pair (i: INTEGER, s: STRING): MY_PAIR is do Result.Create (i, s); end; end To create a sort_my_pair object, the call to create it requires the two lists of appropriate single values as arguments. Code fragment: ints: LIST [INTEGER]; strs: LIST [STRING]; mp: SORT_MY_PAIR; ... the first two lists get filled by some means ... mp.Create (ints, strs); This single call will create, populate, and order the list object "mp". With the proposed improvements to the methods of object creation planned for Eiffel, this solution could be even more elegant, in particular avoiding the need for a specific version of the SORTED_PAIRS class for each different PAIR class. What this does illustrate is the power of genericity, especially when combined with inheritance. I have found in practice that Eiffel's ability to handle truly generic classes is as important, if not more important, than inheritance. I don't think this example could be done anything like as easily in an OOPL with inheritance but not genericity. There are many roads to software reuse if you can navigate them properly! -- Rick Jones Tetra Ltd. Maidenhead, Was it something important? Maybe not Berks, UK What was it you wanted? Tell me again I forgot rick@tetrauk.uucp -- Bob Dylan