Newsgroups: comp.object
Path: utzoo!utgpu!cunews!knight
From: knight@mrco.carleton.ca (Alan Knight)
Subject: generic sort orders
Message-ID: <1991May22.203058.15452@ccs.carleton.ca>
Sender: news@ccs.carleton.ca (news)
Organization: Carleton University, Ottawa, Canada
References: <1991May21.064913.16149@netcom.COM> <1991May22.012821.12048@tkou02.enet.dec.com> <1991May22.183044.5634@Think.COM>
Distribution: comp
Date: Wed, 22 May 1991 20:30:58 GMT

In article <1991May22.183044.5634@Think.COM> barmar@think.com writes:
>In article <1991May22.012821.12048@tkou02.enet.dec.com> diamond@jit533.enet@tkou02.enet.dec.com (Norman Diamond) writes:
>>Responsibility for specifying a "<" operation belongs to the call site.
>
>Which then requires the call site to know about all the possible types of
>things it will compare, which is contrary to object orientation.
>
....

>One possible way around this would be for the generic comparison function
>to take a third argument, which would be an object that represents the
>style of comparison being done.  Sorry, I haven't really thought this
>through, but it could contain flags such as case-sensitivity, relative
>priority of fields, etc.  Making it truly generic could be tough, though;
>it would probably work best in a language with good relexive capabilities
>(e.g. the field priorities could be passed in as a list of slot names if
>the language permits accessing slots using computed names, a la CLOS's
>SLOT-VALUE function).
>

The way that this is handled in Smalltalk is fairly trivial.  There
are three things involved, the "sortee", the "sorter", and the
"client" (stupid terminology mine).
    The sortee is the kind of object being compared, which must
provide (one or more) comparison operations (i.e.  there must be some
way to compare strings, numbers, etc.)  These operations must be
generic enough to handle the mixes that arise.  If you want to compare
strings to integers, then you must define some function somewhere that
does this.
    The sorter is, for example, a heap, and it performs all of its
comparison operations in terms of a "sort block", a comparison
function which it is given.
    The client is whoever created the sorter, and it must supply a
comparison function for whatever it's going to compare.  Thus if I
want a sorted collection of strings, I can say

    SortedCollection sortBlock: [:a :b |
       a asUppercase <= b asUppercase].

The sort function defaults to <=.

Thus, rather than trying to make some incredibly general object which
represents all possible comparison orders, you just pass in an
arbitrary function to do the comparisons.  If this is an unusual sort,
the function might be created on the fly.  For more common or more
complex comparison orders there is probably a function that implements
it, e.g. 

    SortedCollection sortBlock: [:aPoint :anotherPoint |
	aPoint angleLessThan: anotherPoint relativeTo:
someReferencePoint].


    


-- 
--
  Alan Knight   knight@mrco.carleton.ca  +1 613 788 5783   Support
  Dept. of Mechanical and Aeronautical Engineering         the
  Carleton University, Ottawa, Ontario, Canada, K1S 5B6    LPF
