Newsgroups: comp.lang.smalltalk
Path: utzoo!utgpu!cunews!knight
From: knight@mrco.carleton.ca (Alan Knight)
Subject: Re: Access methods - New feature ?
Message-ID: <1991Apr25.141642.4560@ccs.carleton.ca>
Sender: news@ccs.carleton.ca (news)
Organization: Carleton University, Ottawa, Canada
References: <VOSS.91Apr23194435@laslo.cs.uiuc.edu> <1991Apr24.153744.24049@ccs.carleton.ca> <VOSS.91Apr24215444@jerry.cs.uiuc.edu>
Date: Thu, 25 Apr 1991 14:16:42 GMT

In article <VOSS.91Apr24215444@jerry.cs.uiuc.edu> voss@cs.uiuc.edu (Bill Voss;;;356-4652;jerry.cs.uiuc.edu) writes:
>------------------------------------------------------------------------------
>First let me say thanks to all my fellow debate partners in this string, both
>the posters, and the emailers.  This is definitely the most fun I've had in
>comp.lang.smalltalk for months.  We have even managed to disagree without
>slipping into a flame war, in my opinion this string is an example of USENET
>at its finest.

Thank you.  I agree that this thread is remarkably civil and
thought-provoking by USENET standards.

(me)
>>   Suppose that I have a set of points, and that I want to sort them.
>>   There's no canonical sorting order for points, so I have to define

>PP.R4 class "Point" method category "comparing" method "<= aPoint" method
>comment says "Answer whether the receiver is 'neither below nor to the right'
>of aPoint."  So you can stick PP.R4 Point's directly into a sorted collection.

This is not a total order.  Try 
  (0 @ 3) <= (3 @ 0)        ==>  false
  (3 @ 0) <= (0 @ 3)        ==>  false

You can put them into a sorted collection, and you will get an answer
back, but it isn't really sorted.  For example, you get.

   (Array with: (3@0) with: (0@3)) asSortedCollection  ==>
        SortedCollection (0@3 3@0 )
   (Array with: (0@3) with: (3@0)) asSortedCollection  ==>
        SortedCollection (3@0 0@3 ) 

(This is also in PP.R4, but is not likely specific to that version).

>
>If you need a different canonical sorting order, then yes I most definitely
>would suggest adding a simple method "xyzCompare:" to class point.  Then use
>the simple and readable sort block [:p1 :p2 |p1 xyzCompare: p2].  Both methods
>will obviously work, but there is an implicit difference in encapsulation.
>
I will agree that there is no particular harm done by using
xyzCompare: p2, but I don't think it gains you very much over the
other approach.  It might be better style though, so I'll concede you
this one.

>>      [ :point1 :point2 | point1 x <= point2 x]
>Would you use that sort block if you KNEW that the internal representation of
>a Point was NOT based on instance variables X and Y?  I like my code to run as

If I wanted to sort by x-coordinate I don't see that I would have any choice.


>I`ld also either name xyzCompare: something like
>	orderByGodzilianSpiral: 
>in this case I've already written my GodzilianSpiral code when I need it again
>OR
>	projectHack12BSorter:
>in which case WHEN I later decide I didn't really need that infinite precision
>asymptotically corrected aglutinated comparison, and could instead get by with
>an 8 way truncated fast shuffle I only need to change code in ONE PLACE.  

  The code for sorting should already be in one place.  The sort block
does not implement a sorting routine, just a comparison, and in the
instances where the comparison was trivially based on a property of
the object which could be considered a key (whether this is part of
the representation or not).  In the case of an even moderately complex
comparison function I would definitely put it in a method.
e.g. 
  aPoint leqInClockwiseRadialOrderWithOrigin: anOriginPoint than: anotherPoint

Although, with regard to the efficiency you like (which I think I just
deleted) for an ordering by key which is expensive it is considerably
more efficient to calculate the property once at the beginning and
then compare keys.
  e.g.  allPoints do: [:eachPoint |
            eachPoint associateProperty: (eachPoint
                GodzilianSpiralNumberWRT: anOrigin)].

(Pretend points have property lists hanging of them.  One could also
use a dictionary or some other mechanism to do this).
This efficiency, however, breaks encapsulation somewhat in that you need to use
a different sorting routine depending on how expensive your ordering is.


>I've never done any finite element analysis, I don't think I could even tell
>you what it is used for.  (My, my, the state of my education.... ;-)
  Doing physical calculations about objects.  e.g. to analyze heat
flow in a weld, break the object being welded into a number (often
large) of regularly shaped elements, and then evaluate your heat
functions at the corners of these objects discretely rather than
continuously throughout the object.  

>
>That said, it sounds as though you are treating Points as simple Records here.
>Extracting out the raw data they contain, and plugging that data into a
>mathematical formula.  There is nothing apriori wrong with doing this.  In
>such a situation the difficult portion is usually the mathematics, not the
>programming.  However, I wouldn't describe it as object oriented programming
>either, it is programming in an imperative style using an object oriented
>language.  I know if someone gave me a problem which involved complex
>mathematical formulas I'ld do the same thing.  I'ld simply plug the formulas
>into my program.  Not all problems require a hammer, and not all problems
>require object oriented programming.  This seems to be one of those cases
>where imperative is better, and imperative programming definitely DOES work
>better with access methods.

Good analysis of the situation.  In fact, IMHO, a lot of the
difference in style between OOP and non-OOP programming is in the
difference in difficulty between different parts of the program.
  Imperative programming assumes that the difficult parts are the
functions, and that data is some other stuff that functions work on.
The important mental shift in OOP is that usually the data are more
important, and that they should be treated as primary with functions
dependent on them.
  However, this is not true in all domains, and certain kinds of
mathematics are examples of this.  For example, there are a great many
integer functions in math (factorial, catalan, fibonacci, etc. etc.).
The natural impulse is to add these as methods in class Integer.
However, these can be very expensive to evaluate, so it's probably
worth caching them, or intermediate results (e.g. for catalan it's a
big win to cache intermediate C(n,k) values).  These could be added as
class variables in class Integer, but pretty soon this gets awfully
messy.
   What's happening is that the mathematical functions and their
associated data are becoming "heavier" than the functions strictly
associated with single integers, and IMHO the correct approach is to
split these functions out into a separate class or classes.  This
sounds a bit like what you are proposing in your P.S.
i.e. 
>P.S.
>Thinking about it a wee bit more, perhaps you could handle a mathematical
>formula in a rather object oriented style by making the formula itself a
>class.


>
>So I need to update my exceptions list.
>
>    Using ACCESS methods is almost always undesirable EXCEPT:
>    1) As class "private" methods.
>    2) To encapsulate an external interface you can't easily change.
>    3) To implement something not easily expressed in an object oriented style.
>		Such as a complex mathematical formula better expressed
>		in an imperative style.

  This sounds reasonable, although it has the potential to be
dangerous given the common mentality that "object-oriented" means good
and "not object-oriented" means bad.  
   "To implement something not easily expressed in an OO style" also
sounds a bit like a "To handle cases where you need to" catchall, but
perhaps that's what it amounts to.


Unrelated P.S.  I definitely think that a Vector should be a subclass
somewhere under Magnitude.  In PPS, probably under ArithmeticValue,
but not Number.  In a number of places Smalltalk treats points like
Vectors of size 2 (e.g. (3@2) * 5), but they're not well-integrated.

-- 
--
  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
