[comp.lang.c++] Why ask an object its type??

cline@cheetah.ece.clarkson.edu (Marshall Cline) (10/05/90)

In article <57751@microsoft.UUCP> bobatk@microsoft.UUCP (Bob ATKINSON) writes:
>Marshall Cline writes:
>>In article <995@halley.UUCP> kelley@halley.UUCP (Michael Kelley) writes:
>>>What are your views on an appropriate name for a run-time function to return
>>>class information?
>>Runtime (weak) typing is wonderful if you want a toy language that will
>>solve toy problems.  Strong typing is nearly essential for programming in
>>the large.  
>Static typing is *orthognal* to being able to query an object to learn about
>some of the characteristics of its type, which is often done by returning
>a class-related object. It is a perfectly reasonable thought to consider
>adding a member fn to C++ objects, say, to return such a CRO.
>	Bob Atkinson
>	Microsoft

I expected to get lots of exciting commentary from the above statements.
But I didn't expect this one.

Yes, in a sense, the *ability* to find out the dynamic type of a referred
object is orthogonal to strong typing.  However the *use* of such a
construct may (and probably does) indicate a weakly typed program.

I'd like to ask a key question: ``WHY ASK AN OBJECT ITS TYPE?''

There are several answers that I can think of, and presumably others
will add some more.

[1] you might ask an object its type to determine if a particular
message is applicable.  This is one of the worst possible (mis)uses of
the CRO concept, since it is the antithesis of strong typing.

[2] you might ask an object its type so you can do a safe down-cast.
This often amounts to the same thing as [1], since if both the static
type of the reference and the dynamic type of the object have the
desired member function, then the (strongly typed) virtual mechanism
is preferred.

[3] if you're reading an object from persistent store (or from a
network wire, etc), you absolutely need to ask it its type since there
is no way for a compiler to statically determine its type.


Of the answers I gave (and I emphasize that others will think of more),
the only one where we really *need* weak typing is persistent objects.

From discussions with others about this issue at C++-At-Work last week,
C++ seems to be headed towards treating persistence as a *language* issue
rather than as a library issue.  Ie: handing the users with a ``CRO''
would tempt them to ``switch on the object type,'' which will lead to
hopelessly bad code.  If instead case [3] is treated at the language
level, we might achieve many of the advantages of a ``CRO'' without the
disadvantages.

Marshall Cline

PS: here's another possible reason to ask an object its type:

[4] another respondent indicated that it's easier to compile weakly typed
OOPLs and hot linking is easier, since all of the type resolution is
pushed off until runtime.

Is compilation of C++ ``too'' difficult?  Probably yes :-), but that's
why compiler writers get paid so much!  Seriously, making the language
easier to compile is nice, however the type checking mechanism is rather
straightforward.  Existence proof: Turbo-C++ compiles C++ code only about
30% slower than TC compiled typical C code (whatever `typical' means! :-).
--
PS: If your company is interested in on-site C++/OOD training, drop me a line!
PPS: Career search in progress; ECE faculty; research oriented; will send vita.
--
Marshall Cline / Asst.Prof / ECE Dept / Clarkson Univ / Potsdam, NY 13676
cline@sun.soe.clarkson.edu / Bitnet:BH0W@CLUTX / uunet!clutx.clarkson.edu!bh0w
Voice: 315-268-3868 / Secretary: 315-268-6511 / FAX: 315-268-7600

cline@cheetah.ece.clarkson.edu (Marshall Cline) (10/05/90)

In article <CLINE.90Oct4141942@cheetah.ece.clarkson.edu> cline@cheetah.ece.clarkson.edu (Marshall Cline) writes:
>I'd like to ask a key question: ``WHY ASK AN OBJECT ITS TYPE?''

I failed to give the most obvious answer: ``because you don't know its type''

This is the crux of the strong vs weak typing issue.  Ie: if you *need* to
know more type information than can be statically determined, then you
*need* some sort of CRO (class related object).  But if you need more type
information than is statically determinable, your program is weakly typed by
definition, since it relies on dynamic type checks.

A (good) example of where this is needed is persistence: you don't/can't
know the type of the object at compile-time, so you *need* some help from
the runtime.  One solution is to do the type verification at the moment you
read the thing in; Ie: tell the persistent storage device ``I the programmer
believe the next object you'll hand me is a Foible [or some subtype
thereof], and I expect you to holler at me right now if it's not.''  The
persistent storage device gives you a *typed* handle (probably a wide ptr)
to the Foible, and from that point on you can use it in a statically
verifiable (strongly typed) manner.

[ NB: The idea of dynamic typing upon reading an object certainly isn't
original with me.  Doug Lea and I have discussed the matter, and we got it
from at least one published reference, but I don't have the reference handy
(which means: ``Duh... I forgot'' :-) ]

Marshall Cline
--
PS: If your company is interested in on-site C++/OOD training, drop me a line!
PPS: Career search in progress; ECE faculty; research oriented; will send vita.
--
Marshall Cline / Asst.Prof / ECE Dept / Clarkson Univ / Potsdam, NY 13676
cline@sun.soe.clarkson.edu / Bitnet:BH0W@CLUTX / uunet!clutx.clarkson.edu!bh0w
Voice: 315-268-3868 / Secretary: 315-268-6511 / FAX: 315-268-7600

dlw@odi.com (Dan Weinreb) (10/05/90)

In article <CLINE.90Oct4141942@cheetah.ece.clarkson.edu> cline@cheetah.ece.clarkson.edu (Marshall Cline) writes:

   [1] you might ask an object its type to determine if a particular
   message is applicable.  This is one of the worst possible (mis)uses of
   the CRO concept, since it is the antithesis of strong typing.

However, it's a very useful ability for an interactive debugger, or
an interactive data-structure browser.  A browser must be written
on Monday to work on data types that have not even been thought of
by a programmer until Tuesday.

   [4] another respondent indicated that it's easier to compile weakly typed
   OOPLs and hot linking is easier, since all of the type resolution is
   pushed off until runtime.

No, what he said was that it is easier to build an interactive,
incremental programming environment if you can determine types at
runtime than if all type information is lost at compile time.  That's
not the same thing.  There is a lot more to such an environment than
"compile a bunch of text files and produce an executable file, load,
and go".

vaughan@mcc.com (Paul Vaughan) (10/06/90)

   From: cline@cheetah.ece.clarkson.edu (Marshall Cline)
 . . .
   I'd like to ask a key question: ``WHY ASK AN OBJECT ITS TYPE?''

   There are several answers that I can think of, and presumably others
   will add some more.

   [1] you might ask an object its type to determine if a particular
   message is applicable.  This is one of the worst possible (mis)uses of
   the CRO concept, since it is the antithesis of strong typing.

   [2] you might ask an object its type so you can do a safe down-cast.
   This often amounts to the same thing as [1], since if both the static
   type of the reference and the dynamic type of the object have the
   desired member function, then the (strongly typed) virtual mechanism
   is preferred.

   [3] if you're reading an object from persistent store (or from a
   network wire, etc), you absolutely need to ask it its type since there
   is no way for a compiler to statically determine its type.


We occassionally do 2.  You note that this is similar to reason 1, but
knowing the type is a little more fundamental than knowing if a
particular message is applicable.  However, the main reason we do this
is to accomplish modularity.  One part of the program can really only
deal with types it understands but the communication between the parts
of the program uses a particular base type.  There are reasons not to
put all the methods onto the base type.

We also use run-time type information for other purposes.  For
instance, we dynamically generate, compile and link code from user
input.  Knowing the type is important for writing out the code and
giving the user the most power.  Also, we essentially allow users (of
our application) to interactively make pointer assignments.  For this
we do a run-time check just like the compiler would have done if it
were a code statement.  About the only alternative is to put all
possible methods on the base class with null definitions.  However,
this eventually becomes equivalent to programming with ordinary C
structs and functions.



 Paul Vaughan, MCC CAD Program | ARPA: vaughan@mcc.com | Phone: [512] 338-3639
 Box 200195, Austin, TX 78720  | UUCP: ...!cs.utexas.edu!milano!cadillac!vaughan

rae@gpu.utcs.toronto.edu (Reid Ellis) (10/07/90)

In reference to casting of base objects to their derivatives, I'd like to
offer a mechanism that does not sacrifice strong typing while at the same time
incurring a cost of a method call and a minimum number of methods in the base
class [i.e. not requiring all virtual methods for all derivatives to be
declared in the base class].  I call it a `safe downcast'.

Given a base class, "B", and a derived class, "D", we define a method in
the base class, "virtual D* B::asD()".  The base class defines this function
as failing an assertion [i.e. a panic(), exit(1), what have you] while the
derived class defines it as "return this;".

This allows functionality to be added to derived classes without having an
impact on the base class' interface.  However, deriving new classes incurs the
cost of adding an "as*()" method to the base class, but only if such
functionality is required.

Note that this is hierarchical in that if we now derive "F" from "D", we define
"F* D::asF()", and can then say "bPtr->asD()->asF()->fMethod()".

An alternative to invoking "panic()" in the base class method is to simply
return NULL, which allows for error checking on failure.  But it makes
statements such as "x->asD()->asF->fMethod()" illegal, or at least unwise at
best.

Is this original, or is it already in use somewhere like the NIH library?

Relevant previous dicussion follows.  Hit 'n' [or whatever] to skip.  What
does xrn do with ^L's? ...

Marshall Cline <cline@cheetah.ece.clarkson.edu>
	I'd like to ask a key question: ``WHY ASK AN OBJECT ITS TYPE?''

	[2] you might ask an object its type so you can do a safe
	down-cast. ... the (strongly typed) virtual mechanism is
	preferred.

Paul Vaughan <vaughan@mcc.com> argues that casting from base to
derived objects accomplishes modularity:

	One part of the program can really only deal with types it
	understands but the communication between the parts of the
	program uses a particular base type.  
	
	There are reasons not to put all the methods onto the base
	type. ... About the only alternative is to put all
	possible methods on the base class with null definitions.
	However, this eventually becomes equivalent to programming
	with ordinary C structs and functions.
--
Reid Ellis  264 Broadway Avenue, Toronto ON, M4P 1V9               Canada
rae@gpu.utcs.toronto.edu || rae%alias@csri.toronto.edu || +1 416 487 1383