message == virtual functions ? 
Author Message
 message == virtual functions ?

        I'm writing a paper on messages in Smalltalk-80 and virtual
functions in C-plus-plus. Could someone do me a favour by providing me
some basic facts on this topic ?

Peter Kan



Fri, 11 Sep 1998 03:00:00 GMT  
 message == virtual functions ?

Quote:

>         I'm writing a paper on messages in smalltalk-80 and virtual
> functions in C-plus-plus. Could someone do me a favour by providing me
> some basic facts on this topic ?

> Peter Kan

The term "message" appears to mean different things to different people.  

In the Smalltalk community, it refers to a method call specification that
will result in some unknown method being executed, such that the executed
method has the same "selector" (name) as that of the message, and is a
method in the inheritance hierarchy of the object that is the message
"receiver."  The "receiver" of a message is really just a special argument
of the method, and a method is really just a function that is invoked by
sending a message. The language-independent term for this is "dynamic
function dispatching."

Dynamic function dispatching means that the function that actually
gets executed is determined dynamically each time the function is
invoked--not "statically" during program translation from source code to
object code, nor "just once" during the load/link process.

The language CLOS has generalized the original Smalltalk messaging model.
The Smalltalk model distinguishes one argument of a function, called the
receiver, that is the only value (other than the function name) that is
used to "dispatch" (select) which function should be executed when the
name of a function is used to specify function invocation.  The CLOS model
generalizes that by permitting function dispatch to depend on any or all
arguments of the function.  Methods that are dispatched (selected for
execution) based on the value of two or more arguments are called
"multimethods."

Generically, then, a message is a function call that dynamically dispatches
a function based on the abstract function name and the value or values  
(at runtime) of one or more of the arguments.  And a method is a function
selected for execution by sending a message (dynamic dispatching).

Some people hold that a function call is not a message unless the receiving
object responds to the message in a separate thread from the sender.  This
is simply a terminology dispute.  It has nothing to do with fundamental
concepts.

Others hold that the syntax used to call a function determines whether or
not the "function call" is a message.  For example, they would say that
"anObject print" is an example of sending the message "print" to
"anObject," but that "print(anObject)" is a function call--regardless
of whether or not "anObject print" and/or "print(anObject)" were statically
or dynamically dispatched.  Note that neither syntax forces any particular
function dispatching mechanism (as long as you are free to use or implement
any compiler of your choice).  Again, this is a trivial terminology
dispute.

And don't forget that there are languages with objects, messages and
methods--but without classes (e.g., Self).  So the definition of "method"
and "message" should not depend on the concept of "class."

The C++ virtual function qualifies as a method based on the above
definition--but it is constrained in a way that does not apply to
Smalltalk.  The constraint that applies to a C++ virtual function
(but does not apply to a Smalltalk message/method) is that the function
that is dynamically dispatched must be in the inheritance hierarchy
of the class that is specified as the static type constraint of the
variable that holds the receiver of the message.

Example:

        Point * p;
        p->rotateBy(90); /* where rotateBy() is a virtual function */.

The compiler will not let you assign to p any pointer that does not
point to an instance of either class Point or some subclass of Point.
So the actual function that executues must be some function named
"rotateBy" that is defined as a "member function" in Point or one of the
subclasses of Point (such as CartesianPoint or PolarPoint).  However,
if there is also a "rotateBy" function in the class SpatialCoordinate,
but SpatialCoordinate is not a subclass of Point, then that particular
implementation of "rotateBy" could never be dispatched by the above
function call--because the object pointed to by p could not be an instance
of SpatialCoordinate.  And of course, the compiler and linker take full
advantage of this constraint, so type casting and/or pointer aliasing can
cause "type errors" (where a function is executed with a receiver for
which it was never intended). The upside is that this constrained form of
dynamic dispatching is much easier to implement than Smalltalk's more
general form.  But in Smalltalk, "type errors" due to improper type casting
and/or pointer aliasing cannot occur.

Smalltalk objects completely encapsulate their behavior.  The "class" of
a Smalltalk object is part of the object's state.  Assigning an object
to a variable preserves the class of the object, just like assigning
an RGBColor from one variable to another preserves the blue intensity
of the RGB color.

Most traditional languages are "value-oriented," which means that values
do not completely (or at all) encapsulate state and/or behavior. An
"object" in C++ **can** completely encapsulate its state--but not its
behavior, because the class of a C++ "object" is completely determined by
what variable is holding it (in other words, by its address).  So in my
opinion, C++ "objects" are more like non-object "values."

So in Smalltalk, what happens when you send message to an object is
completely determined by the object itself (that is, the encapsulated
value), not by the variable that happens to be holding the object.  But
in C++ and most other languages, the result of "sending a message" or
"invoking a function" is completely (or mostly) determined by the type
or "class" constraint that is statically associated with the variable
(or address) that is holding the value.

--Alan



Fri, 11 Sep 1998 03:00:00 GMT  
 message == virtual functions ?

Quote:

>But in Smalltalk, "type errors" due to improper type casting
>and/or pointer aliasing cannot occur.

Well, if you don't have types, you don't have type errors, I suppose.
They just get called "Unexpected message" instead.

Quote:
>the class of a C++ "object" is completely determined by
>what variable is holding it (in other words, by its address).

No, in C++ the same variable can on different occasions hold pointers to
objects of different classes (provided the objects' classes are inherited
from the variable's class).  What happens when p->rotateBy(90) is invoked
will depend on the class of the object that p points to at run time -- as
in Smalltalk.

The difference is that in C++ the possibilities are limited at
compile-time by the type system, in Smalltalk the possibilities are
limited at run-time by which objects actually have a method for the given
message.

___

    School of Information Systems, Univ. of East Anglia, Norwich, U.K.



Sun, 20 Sep 1998 03:00:00 GMT  
 message == virtual functions ?

Quote:



> >But in Smalltalk, "type errors" due to improper type casting
> >and/or pointer aliasing cannot occur.

> Well, if you don't have types, you don't have type errors, I suppose.
> They just get called "Unexpected message" instead.

No, that is not a type error, but the dynamic detection and prevention
of a type error.  A type error would be applying the machine instruction
for integer addition to a floating point value, and then using the result
as though it had any meaning.  Smalltalk is strongly typed because such
type errors are flatly impossible.  That is not true of C++.

Quote:
> >the class of a C++ "object" is completely determined by
> >what variable is holding it (in other words, by its address).

> No, in C++ the same variable can on different occasions hold pointers to
> objects of different classes (provided the objects' classes are inherited
> from the variable's class).  What happens when p->rotateBy(90) is invoked
> will depend on the class of the object that p points to at run time -- as
> in Smalltalk.

> The difference is that in C++ the possibilities are limited at
> compile-time by the type system, in Smalltalk the possibilities are
> limited at run-time by which objects actually have a method for the given
> message.

> ___

>     School of Information Systems, Univ. of East Anglia, Norwich, U.K.

Yes, I knew that.  My language was admittedly imprecise, and I should have
stated my point better. Let me rephrase: the class of the object is completely
determined by the type constraint on the variable that holds it, because it is
either allowed to be precisely one type/class, or a finite set of them that is
completely determined no later than at link time.  The allowable set cannot be
changed at run time, and is determined by the type constraint associated with
the variable.  The real issue is the improper coupling of variable to class,
not whether the constraint allows either only one class or any class in the
sub-hierarchy of the specified class.  If you must have "type constraints"
for variables, they should enforce interface conformance, not conformance to
some class (implementation) hierarchy.  This is one of the big improvements
the Java designers made with respect to C++.

--Alan



Sun, 20 Sep 1998 03:00:00 GMT  
 
 [ 4 post ] 

 Relevant Pages 

1. Replace standard MESSAGE function in C4 with own message function

2. Ultrix-32 Virtual memory PDP-11 fortran 77 error message

3. Pure Virtual Function Call

4. Pure Virtual Function Called

5. Pure Virtual Function Call

6. Implementing virtual functions that return reference to self

7. C++ virtual function mechanism in Ada ?

8. virtual functions in ada95

9. I just had a very silly idea - self modifying code to implement virtual functions

10. virtual C++ functions in Ada?

11. php virtual() function

12. making virtual functions in CL

 

 
Powered by phpBB® Forum Software