[comp.lang.misc] Languages that allow extensions to classes

new@udel.EDU (Darren New) (04/12/90)

One feature of Smalltalk that I really like and use is the ability to
put methods from one class into several files.  This allows, for example,
for the extention of already-defined classes with new methods.

Example: I wish to extend Point and Rectangle to include a "scaleTo:"
method.  In Smalltalk, that method can be included into my application
without disturbing the sources for the system and without recompilation
of anything in the system. Even addition of new instance variables
is possible (in ParcPlace systems, at least).  I find this a MAJOR factor
in software reusability.  

In C++, I (think) I have to change the header file, thereby requiring me
to recompile all sources that reference that object. In Objective-C,
I don't know if this is possible, especially without the sources
to the other methods.  In Eiffel (sp?) I understand that each class is
defined within a single file, forcing me to -change- at least one system
file (thereby maybe corrupting other hopefully-non-conflicting applications).
I think adding overloaded functions for Ada types requires changes to
the definition file, does it not?  Or is that only for opaque types?

In 2OL (my own experimental language) overloaded functions and messages 
automatically include themselves into the correct tables when compiled,
thereby requiring no changes to somebody else's sources.

Is my analysis of C++, Objective-C, and Eiffel correct?  Does anybody know
of other languages which allow the user to extend functionality of system
classes/libraries/etc without changing files where the old stuff is
defined?  How about Ada

preston@titan.rice.edu (Preston Briggs) (04/12/90)

In article <16560@estelle.udel.EDU> new@ee.udel.edu (Darren New) writes:

>Does anybody know
>of other languages which allow the user to extend functionality of system
>classes/libraries/etc without changing files where the old stuff is
>defined?

Oberon and Object Oberon can do things like this.

Oberon is reported in Software - Practice and Experience, July, 1988.

Object Oberon is introduced in a paper published in an
issue of Structured Programming (sorry, I'm not sure which, probably in 1989).

Both of these are talked about occasionally in comp.lang.modula2
--
Preston Briggs				looking for the great leap forward
preston@titan.rice.edu

mikeb@coho.ee.ubc.ca (Mike Bolotski) (04/12/90)

In article <16560@estelle.udel.EDU> new@ee.udel.edu (Darren New) writes:
>One feature of Smalltalk that I really like and use is the ability to
>put methods from one class into several files.  This allows, for example,
>for the extention of already-defined classes with new methods.

>In C++, I (think) I have to change the header file, thereby requiring me

Yes..

> [..]                                                    Does anybody know
>of other languages which allow the user to extend functionality of system
>classes/libraries/etc without changing files where the old stuff is
>defined? 

Well, CLOS (Common Lisp Object System) for one.  And I really dislike 
the above feature, actually.  In C++ the header file documents the entire
behaviour of the class.  In CLOS that information is spread out all over
the source files.   Not an example of proper software engineering, IMHO. 

Mike Bolotski, Department of Electrical Engineering,
               University of British Columbia, Vancouver, Canada 
mikeb@salmon.ee.ubc.ca             | mikeb%salmon.ee.ubc.ca@relay.ubc.ca
salmon.ee.ubc.ca!mikeb@uunet.uu.net| uunet!ubc-cs!salmon.ee.ubc.ca!mikeb

briscoe-duke@CS.YALE.EDU (Duke Briscoe) (04/12/90)

In article <1238@fs1.ee.ubc.ca> mikeb@coho.ee.ubc.ca (Mike Bolotski) writes:
>Well, CLOS (Common Lisp Object System) for one.  And I really dislike 
>the above feature, actually.  In C++ the header file documents the entire
>behaviour of the class.  In CLOS that information is spread out all over
>the source files.   Not an example of proper software engineering, IMHO. 

Don't some CLOS systems have a browser which allows you to look at
(and edit) the source for a class' methods regardless of what file was
loaded to define the method?  I'm not a big fan of depending on plain
text files as a way of representing programs; richer data structures
(like what a browser uses) would be preferable, which are offered to
some extent by Smalltalk and some Lisp environments.

I think the other issue is whether a language has the capability of
incrementally extending or redefining definitions without having to do
massive recompilation.  This often involves an extra level of
indirection which has a performance price, but the performance price
can be "unpaid" by having a "final version" compiler which eliminates
the indirection, since that feature is mainly needed only during
development.  There are also security concerns if it is possible to
redefine the behavior of previously existent objects, but that can be
dealt with if necessary.

--Duke

new@udel.EDU (Darren New) (04/12/90)

In article <22413@cs.yale.edu> briscoe-duke@CS.YALE.EDU (Duke Briscoe) writes:
>I think the other issue is whether a language has the capability of
>incrementally extending or redefining definitions without having to do
>massive recompilation.  

My original post which started this thread was meant to examine reusability.
My example is this:  I am working with a program called WISE, which is an
interpreter for a language called Estelle.  I am adding "hooks" into WISE
in order that at key points it calls my program (called GROPE).  When
new versions of WISE are released, I simply run the change manager
against all three versions and see what I've changed that the new
version also changed (actually, it's harder than that, but should be that
easy).  Given the old WISE, the old GROPE, and the new WISE, generating
the new GROPE is fairly simple.  Any changes to WISE that are not in the
area that GROPE changed do not need to be examined.  If I had to change 
all the header files for all the portions of the WISE system I extended,
these changes would have to be redone.  This problem is similar to
upgrading (say) a Unix system to a new release of the OS: you need
to save /etc/passwd, certain config stuff, /usr/local, and various other
files. You then install the new system and see what files you saved have
changed in the new system (new deamons in initrc that need to be run) and 
so on. Problematically, you MUST change distribution files in Unix in order
to configure your system.  I don't need to change distribution files in
Smalltalk in order to extend a system with a new capability.  The compilation
issue is less of a problem for me.  How about Ada?  I'm still not sure
whether all functions on a given type (or returning a given type?) must be
declared in the same header file.    -- Darren

lgm@cbnewsc.ATT.COM (lawrence.g.mayka) (04/12/90)

In article <22413@cs.yale.edu> briscoe-duke@CS.YALE.EDU (Duke Briscoe) writes:
>Don't some CLOS systems have a browser which allows you to look at
>(and edit) the source for a class' methods regardless of what file was
>loaded to define the method?  I'm not a big fan of depending on plain
>text files as a way of representing programs; richer data structures
>(like what a browser uses) would be preferable, which are offered to
>some extent by Smalltalk and some Lisp environments.

Yes.  In general, Common Lisp and Smalltalk are designed to take
advantage of any advanced software development environment
technology that may be present.  When circumstances preclude the
use of such technology, one can still fall back on more
traditional techniques, such as the one-class-per-file convention.

I would also point out that the Common Lisp Object System is a
"grand unification" of functional and object-oriented
programming.  A functional view would group methods by generic
function (method selector) rather than by class.  CLOS supports
both the functional (generic-function-based) and object-oriented
(class-based) views.

Related to this also is CLOS' ability to specialize a method on
more than one argument (i.e., not just the first).  Such a
"multimethod" belongs, in a sense, to two or more classes, so its
logical role in the software system does not really correspond to
its textual placement, which is of course limited to a single file
(unless one's textual programs reside on a hypertext system).

>I think the other issue is whether a language has the capability of
>incrementally extending or redefining definitions without having to do
>massive recompilation.  This often involves an extra level of

Yes.  One would like the ability to define new behaviors (methods)
for any existing class and any existing objects, even for basic
types such as integers and strings, without disturbing existing
software at all.  CLOS permits one to do just that.


	Lawrence G. Mayka
	AT&T Bell Laboratories
	lgm@ihlpf.att.com

Standard disclaimer.

Rick_R_Kitts@cup.portal.com (04/12/90)

 Adding a member function to a C++ class does not require recompilation
of other source files which access the class unless the size of the
class has changed (i.e. you added members). Also, unless you need to
access the private parts of a class there is no real reason to actually
modify the class definition itself. (Perhaps) the easiest thing to do
is to make a derived (sub) class of the base (super) class which contains
the method you want to add. Note that following this scheme could get
quite messy since you could end up with a bunch of class hierarchy trees.

	Rick

rkitts@slc.slac.stanford.edu

andyn@stpstn.UUCP (Andy Novobilski) (04/12/90)

In article <16560@estelle.udel.EDU> new@ee.udel.edu (Darren New) writes:
>One feature of Smalltalk that I really like and use is the ability to
>put methods from one class into several files.  This allows, for example,
>for the extention of already-defined classes with new methods.
>
>... In Objective-C, I don't know if this is possible, especially without 
> the sources to the other methods.  
> ...
>Is my analysis of C++, Objective-C, and Eiffel correct?  ...


Darren,

The Objective-C language supports the extension of pre-existing 
classes and class libraries by allowing one class to "pose" as 
another.  This mechanism is invoked at runtime by the Objective-C 
object model and allows a programmer to insert behavior (no data) 
into the class hierarchy structure.  

The programmer uses the poseAs capabilities by defining a new 
class (methods only, no instance variables allowed) that sends a 
"poseAs:" message at initialization time indicating the class it 
wishes to pose as.  This causes the message lookup function to 
check if the method is located in the posing class before checking
in the original class that was posed as.

The pose as functionality is made possible by Objective-C's use
of dynamic binding to resolve what method should supply the 
requested behavior at message time.  The use of dynamic binding 
also allows a programmer to change the methods of a class 
definition without having to recompile classes that subclass from 
it.  However, if a change is made to an instance variable, then
all subclasses of that class must be recompiled.

If you have any additional questions, please feel free to contact
us (or myself) at Stepstone.

Andy N.

-- 
Andy Novobilski     | The Stepstone Corp.  | The expressed views have been
andyn@stepstone.com | 75 Glen Rd.          | approved by a committee of three:
(203)426-1875       | Sandy Hook, CT 06482 | the goldfish, blackfish, and me.

mikeb@ee.ubc.ca (Mike Bolotski) (04/13/90)

In article <22413@cs.yale.edu>, briscoe-duke@CS.YALE.EDU (Duke Briscoe) writes:
|> Don't some CLOS systems have a browser which allows you to look at
|> (and edit) the source for a class' methods regardless of what file was
|> loaded to define the method?  I'm not a big fan of depending on plain
|> text files as a way of representing programs; richer data structures
|> (like what a browser uses) would be preferable, which are offered to
|> some extent by Smalltalk and some Lisp environments.

Such a browser would be quite welcome but neither the Apollo nor Sun
CL systems that I use include it.   In any case, the browser is a
reflection of the *environment*, not of the *language* itself.   
C++ enforces certain software engineering principles that
CLOS doesn't.  Whether those principles are a good idea is a different
argument

But this shouldn't really be surprising, seeing as CLOS allows you to
dig out any instance variable/slot no matter  how hard you try to hide
it.  A reflection of the CL philosophy of bypassing the package
mechanism by the simple expedient of using :: instead of :  .

|> I think the other issue is whether a language has the capability of
|> incrementally extending or redefining definitions without having to
do |> massive recompilation.  This often involves an extra level of |>
indirection which has a performance price, but the performance price |>
can be "unpaid" by having a "final version" compiler which eliminates
|> the indirection, since that feature is mainly needed only during

Very very interesting idea.

Mike Bolotski, Department of Electrical Engineering,
               University of British Columbia, Vancouver, Canada 
mikeb@salmon.ee.ubc.ca             | mikeb%salmon.ee.ubc.ca@relay.ubc.ca

lgm@cbnewsc.ATT.COM (lawrence.g.mayka) (04/14/90)

In article <28835@cup.portal.com> Rick_R_Kitts@cup.portal.com writes:
> Adding a member function to a C++ class does not require recompilation
>of other source files which access the class unless the size of the
>class has changed (i.e. you added members). Also, unless you need to

This understates the situation a bit.  The following situations
may require recompilation of other source files.

- Adding a virtual function may not update the virtual function
table (without additional recompilation).

- Adding the first virtual function to a class may insert a new
(hidden) member, the virtual function table pointer, thus changing
the size of the class structure.

- Adding a virtual function that precedes all others textually may
cause the virtual function table pointer to occur at a different
location within the class structure, effectively shuffling members.

- Adding a virtual function anywhere other than at the end may
shuffle the virtual function table entries and thus change the
offset needed to call each virtual function.

- Adding a member function may shadow an external function or type
of the same name.

- Adding a member function with an overloaded name may shadow (via
the overloading rules) another member function overloaded on that
same name.

Those are the only cases I can think of *offhand*.

In general, the C++ language assumes global consistency (i.e.,
global recompilation on any change to anything).  Anything less
may give implementation-dependent results.


	Lawrence G. Mayka
	AT&T Bell Laboratories
	lgm@ihlpf.att.com

Standard disclaimer.