Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!mailrus!cornell!rochester!udel!new From: new@udel.EDU (Darren New) Newsgroups: comp.lang.misc Subject: Re: Functional and Object Oriented Languages compared Keywords: functional languages object oriented ML smalltalk c++ Message-ID: <17673@louie.udel.EDU> Date: 15 Jun 89 03:17:01 GMT References: <11213@orstcs.CS.ORST.EDU> Sender: usenet@udel.EDU Reply-To: new@udel.EDU (Darren New) Organization: University of Delaware Lines: 102 In article <11213@orstcs.CS.ORST.EDU> budd@mist.CS.ORST.EDU (Tim Budd) writes: >On the surface, functional programming as in ML and object oriented >programming as in Smalltalk or C++ often seem to be emphasizing different >sides of the same coin. >In ML (footnote (1)) we define a union type, >and a function, as in: > >datatype VEHICLE = Car of kind * weight | Truck of weight * kind | Bike; >fun weight(Car(_, w)) = w > | weight(Truck(w,_)) = w > | weight Bike = 15; > >In OOPLS (generic object oriented programming languages) we define a >class Vehicle with subclasses Car, Truck and Bike, and a function weight in >each. Now in either case given an instance of a vehicle we can compute its >weight. ML chooses to group around functions, while OOPLS group around >classes, but it would seem that the same behavior is available in both. (2) Certainly. The difference is in the organization. In ML, if I add a new type (say, boat), I must find all functions that boat uses and change them. In complex cases this could break much code (if you are careless). In Smalltalk, I add the new class and then I must define in that class all functions (messages) which I want to use (like weight, size, speed, ...). In either case, I can forget to change something and when that function is used with the new object I will get an error. In truth, these are different sides of the coin. Both languages have types and functions. In ML, functions talk about types and in ST types talk about functions. >EXCEPT - there is one very important facility that we can use in functional >languages that we seem not to have available in OOPLS. Suppose we have >an array of vehicles, and a functional sum that takes a plus reduction of >an array using a user supplied function on each element of the array. >We can compute the sum of the weights of the vehicles using something >like ``sum (vehiclearray, weight)''. Since message selectors, such as >``weight'' are not first class entities in OOPLS, there does not seem to >be any similar technique that can be used. (Before someone else mentions >it, yes I know we could use >``vehiclearray inject: 0 into: [:x :y | x + y weight]'' in smalltalk, >but this doesn't seem quite the same and my point that message selectors >are not first class is still valid). This is exactly how the plus-reduction would be done. The '+' symbol above represents not a particular method but rather a message (function name, rather than function body). Also, the 'weight' symbol represents a message and not a method. In both cases, the method (body) used for the function call is looked up by the interpreter based on the class (type) of x or y respectively. The inject:into: message is used precisely for doing this. In the above paragraph, the ``sum (vehiclearray, weight)'' line seems to be a function call, whereas the inject:into: would be equivalent to the body of the function sum. Maybe this is your confusion? These two seem the same to me except for the coding of the weight function itself. >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? >If the answer is yes, what is a reasonable way that this can be implemented? Again, I think you are confusing the issue by trying to force smalltalk into the ML mold. You seem to be confused, in particular, about the difference between messages and methods: a message plus a class -> a method. Thus, speaking of "various weight functions" is confusing. It is either the weight message, which returns the weight of the object to which it is sent, or it is the weight method of the bike class, which returns 15. The methods are different entities, and the message is the means by which a method of a particular class is accessed and invoked. In terms of being able to pass "weight" as an argument itself, to define your sum function, you could say (this is off-hand, so no flames if wrong...): plusRed: aSymbol "This is in class Array" | i | i _ 0. self do: [: j | i _ i + (j perform: aSymbol)]. ^ i Thu, the call "sum(vehiclearray, weight)" would become vehiclearray plusRed: #weight. This seems pretty first-class to me. Note that in Smalltalk, methods as well as messages are first-class. (Actually, messages are not objects at all, but the names of messages are first-class (symbols) and going from the name to the message is done via perform:). Hope this clarifies. The point of OOPLs is to separate everything that a bike does from everything that a car does. Thus, weight gets split up instead of put all in one function. This makes it easy to reuse bike code in some other program without dragging along cars, trucks, boats, etc. In ML, it would be tedious to pull all that apart, I suspect. Note that little if any of this holds true for C++, as C++ does not have dynamic binding except for an extra level of indirection when virtual functions are used. The "object oriented" part of C++ could quite easily be done by hand while coding. However, it is still OO in the sense of the previous paragraph. - Darren New UDel's Smalltalk Programmer (Amongst several???)