Newsgroups: comp.lang.smalltalk Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!wuarchive!m.cs.uiuc.edu!cs.uiuc.edu!voss From: voss@cs.uiuc.edu (Bill Voss;;;356-4652;jerry.cs.uiuc.edu) Subject: Re: Access methods - New feature ? In-Reply-To: knight@mrco.carleton.ca's message of Wed, 24 Apr 1991 15:37:44 GMT Message-ID: Sender: news@m.cs.uiuc.edu (News Database (admin-Mike Schwager)) Nntp-Posting-Host: jerry.cs.uiuc.edu Organization: Typed Smalltalk Group, Dept of Comp Sci, Univ of IL in Urbana. References: <1991Apr23.010026.25098@ccs.carleton.ca> <1991Apr24.153744.24049@ccs.carleton.ca> Date: 24 Apr 91 21:54:44 Lines: 120 Trying again with a different machine. Sorry if the other one made it part way out. -- HUGE SIGH. ------------------------------------------------------------------------------ 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. Now replying to Alan's reply to my....... > OK, here are some examples, still using x and y. I wish I'ld never accepted Point as an example. SIGH. > 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 > one. I could define my sortBlock as > > [ :point1 :point2 | point1 x <= point2 x] > OR [ :point1 :point2 | point1 y <= point2 y]. > > On the other hand, to avoid accessing the representation, I could > write > [:point1 :point2 | point1 xIsLessThanOrEqualXFor: point2] > > I contend that there is no additional encapsulation in the second > example, and no good reason to use it. Of course for generality there > should really be a single sort block. > [:point1 :point2 | (point1 componentInDirection: aVector) <= > (point2 componentInDirection: aVector)] > which is no longer really an access method, but the efficiency gain is > significant enough that I believe a lot of people would write one of > the preceeding forms. 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. 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. > [ :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 fast as possible, so I would try to avoid converting Points needlessly. As an external user asking for x and y, I have no business worrying about a Point's internal representation. As an xyzCompare: method inside of Point I can legitimately take Point's internal representation into consideration. Thus using xyzCompare: I can legitimately make efficiency decisions based on Point's internal representation. 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. (I can also find all such users quickly with "senders".) ============================================================================== > Another, and perhaps a better example is where one needs to know about > internals of more than one class at a time. For example, suppose that > I have a geometric object and I need to do some mathematics on it (I'm > specifically looking at code for doing finite element analysis as I > write this, but think of it in general). This mathematics probably > involves plugging x and y coordinates of some or all of the points > into some fairly complicated equations. > Right now this code is in the finite element, which is (IMHO) where > it belongs, since it has to know a lot more about the details of the > finite element than about the particular points, but it does need to > know x's and y's. I certainly don't think that having the methods > > Point>> findBasisFunctionsForEightNodeBrick: aBrick > findBasisFunctionsForFourNodeQuad: aQuad > findBasisFunctionsForTetrahedron: aTetrahedron > > etc. etc. is in any way a cleaner solution. 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.... ;-) 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. 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. Bill Voss -- voss@cs.uiuc.edu -- Graduate Student in Computer Science 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. You feed it what it needs at instance creation, and then eventually ask it for its value. You would build the big formula with instances of smaller formulas.... hmmm. If anyone out there has an OBJECT ORIENTED way of handling complex mathematical formulas, please start another string and tell us about it. -- Bill Voss INTERNET: billvoss@uiuc.edu UUCP: uunet!uiucuxc!uiucdcs!voss