Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!cs.utexas.edu!csd4.milw.wisc.edu!leah!albanycs!crdgw1!uunet!pdn!oz!alan From: alan@oz.nm.paradyne.com (Alan Lovejoy) Newsgroups: comp.lang.misc Subject: Re: Functional and Object Oriented Languages compared Keywords: functional languages object oriented ML smalltalk c++ Message-ID: <6192@pdn.paradyne.com> Date: 16 Jun 89 02:56:36 GMT References: <11213@orstcs.CS.ORST.EDU> Sender: news@pdn.paradyne.com Reply-To: alan@oz.paradyne.com (Alan Lovejoy) Organization: AT&T Paradyne, Largo, Florida Lines: 104 In article <11213@orstcs.CS.ORST.EDU> budd@mist.CS.ORST.EDU (Tim Budd) writes: >So, the topic for debate today is the question whether method selectors, >such as ``weight'', which are implemented in several classes, should >be considered to be first class objects in their own right. That is, >should we be able to pass ``weight'' as an argument to another function? >Should be various ``weight'' functions, although implemented in different >classes, be considered to be part of a single entity? 1) You have raised an important topic of discussion. 2) The fact that messages are not first class objects in Smalltalk and other OOPLs does impair the functionality of those languages. I have been aware of this problem for many years. 3) A related problem is that there is a fundamental discrepancy between the semantics and usage protocol of the "first argument" of a message (which is the receiver of the message) and any subsequent arguments: a. The method that will be executed in response to a message is determined by the class of the first argument, but not by the class of any subsequent arguments. Hence, associative expressions are not directly supported in mixed-type expressions (they have to be kludged-in using some device such as double dispatching). b. The code of the executed method can not know or depend on the class of the subesequent arguments. But it very definitely can (and very probably will) depend on the class of the receiver or "first" argument. c. Since method code may depend upon the class of the receiver (i.e., source code that is valid if the class of the receiver is A may not be valid if the class of the receiver is not A), it is not possible to safely create procedure (method) abstractions that are independent of the class of any and all arguments (including the "first argument" or receiver). Smalltalk compensates for this situation to some degree by making all classes subclasses of Class Object. Methods defined in class Object can provide most of the desired functionality. But this device is not the most elegant of solutions. Another solution to the problem is to make the syntax for reading and writing state (i.e., instance variables) the same as the syntax for evaluating functions (oh, I guess I mean sending messages :-) :-)). For example, if class RgbColor has the instance variables 'red', 'green' and 'blue,' then the syntax for reading the value of the instance variable 'red' should be "self red" instead of just "red" (the latter being the current syntax). Similarly, the syntax for setting the value of the instance variable blue should be "self blue: 0.5" instead of "blue <- 0.5" (again, the latter being the current syntax). Given this change in syntax, it becomes possible to write instance method code in a more class-independent way. For instance, the method 'initialize' in the class AbstractColor (the superclass of RgbColor) can now be written as: initialize "Initialize a color to black." self red: 0.0. self green: 0.0. self blue: 0.0. ^self Written this way, it does not matter whether or not "self red: 0.0" is a message send to an object whose class does not have the instance variable 'red.' So the method will be valid for the other subclass of AbstractColor--HsiColor--which has the instance variables 'hue,' 'saturation' and 'intensity' instead of 'red,' 'green' and 'blue' (provided, of course that the appropriate methods 'red:', 'green:' and 'blue:' have been defined in HsiColor). Because the same source code for the 'initialize' func...uh, method can now be valid for all subclasses of AbstractColor, the method can be defined once in AbstractColor instead of in each subclass. 4) If messages were first class values, then one could write code such as the following: | aMessage aPoint | aMessage <- Message for: (x: 0 y: 0). aPoint <- Point aMessage. The problem with the above is syntactical: how can the compiler tell that "Point aMessage" means "send the message 'x: 0 y: 0' to Point" and not "send the message 'aMessage' to Point"? There are only two solutions to this problem. Smalltalk uses one of them: the syntax for sending messages whose value is determined statically at compile time and for sending messages whose value is determined dynamically at run time is completely different. For example, the "correct" way to code what is intended in the example above is: | aMessage anArgumentList aPoint | aMessage <- #x:y:. anArgumentList <- #(0 0). aPoint <- Point perform: aMessage with: anArgumentList. The problem with this is that the code is not independent of whether or not the message to be sent is static or dynamic. Therefore, it is impossible to abstract over the code with regard to the property of static or dynamic message values. But this is due to the syntax of Smalltalk. It has nothing to do with the inherent properties of OOPLs. So the other (better) solution to the problem is to create OOPLs whose syntax for sending statically and dynamically determined message values is identical. Alan Lovejoy; alan@pdn; 813-530-2211; AT&T Paradyne: 8550 Ulmerton, Largo, FL. Disclaimer: I do not speak for AT&T Paradyne. They do not speak for me. ______________________________Down with Li Peng!________________________________ Motto: If nanomachines will be able to reconstruct you, YOU AREN'T DEAD YET.