[net.lang] What is Object-Oriented

koved@umcp-cs.UUCP (Larry Koved) (02/05/85)

 
After reading the many definitions of what "object-oriented"
means, I have decided to put in my 2 cents (for whatever that
is worth!).
 
Object-oriented is a rather vague term which has been applied
to many different concepts.  Two areas in which OO has been
used is in programming languages and computer systems (hardware
and operating systems).  Its roots date back to about 1966 in
an infamous article written by Dennis and Van Horn (CACM, March 1966).
Many ideas and concepts were expanded from that paper and developed
during the late 60's and 70's.  Many systems which evolved during
this era were interested in abstraction mechanisms (data types, etc.),
and protection of data (and data objects) in computing systems.
 
What eventually evolved were systems such as Hydra, CLU, Smalltalk,
Multics, Intel 432, IBM System/38, Sward, and many others which
I can't remember offhand.
 
A central themes of these systems was data, procedures, protection,
and abstraction.  Data is "encapsulated" into an object (of a type)
which has a set of protected procedures which are allowed to manipulate
the representation of the object.  Only those procedures which are
defined for the data type are allowed to manipulate the representation
of the object.  Note that procedures are also considered to be
objects (procedure objects).  Also, objects can contain other objects.
(this also gets into the issue of data abstraction.)
 
I could go on for pages, but I will leave that for another time.
I will not pontificate on this subject much more...except:
 
There are two related issues in programming language design which
frequently gets confused with OO programming: overloaded operators
and inheritence.  Having overloaded operators and/or inheritence
(single or multiple) does not determine whether or not a language
is OO.  Each of these is an issue in programming language design
which can and should be considered seperately from the OO issues.
There are languages which use overloading and/or inheritence, but
are not OO, and visa versa.
 
Finally, it should also be noted that there are different degrees of
being OO.  Smalltalk is almost at one extreme, while Modula-2 is almost
at the other extreme.  The performance of the language (instructions
per second) is a major consideration in deciding the degree to which
a language's design is OO.  Being extremely OO is expensive in
processing time and/or space.
 
I will now get down off my soapbox and await for your reactions (flames).
-- 
Spoken: Larry Koved
Arpa:   koved.umcp-cs@CSNet-relay
Uucp:...{allegra,seismo}!umcp-cs!koved

mark@tove.UUCP (Mark Weiser) (02/06/85)

In article <3013@umcp-cs.UUCP> koved@umcp-cs.UUCP (Larry Koved) writes:
>There are languages which use overloading and/or inheritence, but
>are not OO, and visa versa.

I'd be interested in an example of inheritence without OO.  What one
inherits in OO is operators and local variables.  Is there something
else to inherit?

>Finally, it should also be noted that there are different degrees of
>being OO.  Smalltalk is almost at one extreme, while Modula-2 is almost
>at the other extreme.  

Not Fortran or Forth at the other extreme?  Modula-2?  Do you mean
there are different KINDS of OO, with Modula-2 and Smalltalk being
prototypical examples, or do you really mean degrees?

>The performance of the language (instructions
>per second) is a major consideration in deciding the degree to which
>a language's design is OO.  Being extremely OO is expensive in
>processing time and/or space.

Now this is an interesting issue.  Why should OO be expensive?
It need not be, because it need not be a runtime feature of a language.
Smalltalk is mostly interpreted, and so is slow for that reason,
not because it is OO.  The Maryland Flavors Package under Franz
Lisp allows compiled methods, flavors etc, and so runs not too
much slower than bare Lisp.  And a completely statically checked
and implemented OO language should be as fast as any other at runtime.
(Is c++ something like this?  I'm not sure.)
Might be slow to compile with current technology--but we haven't had
much practice at building fast OO compilers.
-- 
Spoken: Mark Weiser 	ARPA:	mark@maryland	Phone: +1-301-454-7817
CSNet:	mark@umcp-cs 	UUCP:	{seismo,allegra}!umcp-cs!mark
USPS: Computer Science Dept., University of Maryland, College Park, MD 20742

koved@tove.UUCP (Larry Koved) (02/06/85)

> In article <3013@umcp-cs.UUCP> koved@umcp-cs.UUCP (Larry Koved) writes:
> >There are languages which use overloading and/or inheritence, but
> >are not OO, and visa versa.
> 
> I'd be interested in an example of inheritence without OO.  What one
> inherits in OO is operators and local variables.  Is there something
> else to inherit?
> 
Lisp Flavors (which you mention below) is an example of a lanugage
which has is a combination of object-oriented and non-object-oriented
features in a single language.  Lisp is not object oriented, but the
flavors package in lisp is object oriented.  I would not classify
Lisp as an object oriented language;  only the flavors part is
object oriented (to a degree).  I do not know of a language which
only has inheritence, but not objects.  A language could be defined
in which a data type could inherit properties of an existing data type.

For example:
In Pascal, if a type (call it A) uses another type in its definition
(call it B), then type A inherits properties of type B.

My thoughts in this area are a little fuzzy since I have not thought
about it very much.

> >Finally, it should also be noted that there are different degrees of
> >being OO.  Smalltalk is almost at one extreme, while Modula-2 is almost
> >at the other extreme.  
> 
> Not Fortran or Forth at the other extreme?  Modula-2?  Do you mean
> there are different KINDS of OO, with Modula-2 and Smalltalk being
> prototypical examples, or do you really mean degrees?

I would probably like to stick with my original statement of there
being extremes in being OO.  Yes, Modula-2 and Smalltalk
prototypical examples of OO languages.
The degrees of which I am speaking are the degrees to which the
language makes the sharp distinction about object manipulation.
In particular, how well the language protects the objects, their
internal representations and access to the procedures which manipulate
the representation.

For example, in Modula-2 (and ADA for that matter), you can hide
the representation and implementation of an object in the implementation
of the modules.  The definition of the object and the procedures which
manipulate the objects can be made public (if so desired), but
those procedures which are not defined to manipulate the object
can not gain access to the object's representation.

The same is true of Smalltalk.  The difference is that Smalltalk
attempts to enforce the rules across all objects which are defined
and instantiated.  This is not so for Modula-2 and ADA where you
can define objects where any procedure can manipulate the internal
representation.

The difference is that Modula-2 allows object representation protection,
but Smalltalk always requires that the object be protected.

> 
> >The performance of the language (instructions
> >per second) is a major consideration in deciding the degree to which
> >a language's design is OO.  Being extremely OO is expensive in
> >processing time and/or space.
> 
> Now this is an interesting issue.  Why should OO be expensive?
> It need not be, because it need not be a runtime feature of a language.
> Smalltalk is mostly interpreted, and so is slow for that reason,
> not because it is OO.  The Maryland Flavors Package under Franz
> Lisp allows compiled methods, flavors etc, and so runs not too
> much slower than bare Lisp.  And a completely statically checked
> and implemented OO language should be as fast as any other at runtime.
> (Is c++ something like this?  I'm not sure.)
> Might be slow to compile with current technology--but we haven't had
> much practice at building fast OO compilers.

Yes, the issue about performance of systems which require protecton
is interesting.  If and when type checking can be done statically,
the cost is much lower.  You make refrence to flavors.  The flavors
part of lisp is object oriented, but the rest of lisp upon which
flavors is implemented is not.  I suspect that this makes a difference.
When looking a security (protection) oriented systems, there are costs
incurred due to the protection mechanisms.  Once you start to do
multi-programming, then you get many different types of protection
problems which do not occur in uni-programming systems (and languages).
This is also a factor in why protected systems incur a heavy cost
at run-time.

> -- 
> Spoken: Mark Weiser 	ARPA:	mark@maryland	Phone: +1-301-454-7817
> CSNet:	mark@umcp-cs 	UUCP:	{seismo,allegra}!umcp-cs!mark
> USPS: Computer Science Dept., University of Maryland, College Park, MD 20742
-- 
Spoken: Larry Koved
Arpa:   koved.umcp-cs@CSNet-relay
Uucp:...{allegra,seismo}!umcp-cs!koved

liz@tove.UUCP (Liz Allen) (02/08/85)

We have had an implementation of a flavors package in Franz lisp
now for about 3 years -- we have found that it has nearly transformed
the way we write lisp programs.  Probably the most useful feature
has been the following:  The ability to send a message to an object
*without* having to know the type of the object.

This gives new meaning to the idea of a generic operation.  Notice
that without this ability, methods would be rather difficult to
inherit since lots of methods send messages "self" -- and, even
though you know "self" has to mix in the flavor the method is
defined for, you don't really know what flavor "self" is.

So, what is really necessary is that you somehow know that the
flavor of the object has methods for the messages you need to send
it.  Probably the best way to do this is to know that (1) the flavor
mixes in some flavor that does define these methods or that (2)
the flavor mixes in a flavor that requires the methods to be defined.
An example of (1) is when you send a message like :print-self to
an object -- vanilla, which is mixed into every flavor in the system
(unless otherwise specified) defines a method for :print-self.  An
example of (2) is when you define a flavor that is just going to
be a mix-in to other flavors.  It can give you certain methods (or
operations) that depend on the fact that the flavors which mix it
in define other methods which (by some necessity) depend on the
other flavor.  For example, a flavor that defines methods to save
information in files may require flavors which mix it in to define
methods for retrieving the information to be stored.

Another example has to do with a parallel activation net I am
implementing.  There are different kinds of nodes in the net (eg,
connected to other nodes in different manners).  Yet there is some
common ground between the nodes.  However, there isn't enough to
define a flavor which will be used to define some nodes *and* be
used as a mix-in to other nodes.  So, I defined a flavor that will
be used as a mix-in to all the nodes.  It contains those methods
that are common to all the nodes and assumes that some of the
methods it sends to "self" will be defined by the node flavors
mixing in this common flavor:

	(defflavor node-mixin (
		; the instance variables
		name		; name of the node
		value		; activation level of the node
		resting-value	; activation level at rest
		...)
	  :mixin
	  :required-methods
		input-arcs	; return a list of the input arcs
		output-arcs	; return a list of the output arcs
	  :gettable-instance-variables name value
	  :settable-instance-variables value
	  )

(More ideas about doing these kinds of things later.)

>> > = Larry Koved
>>   = Mark Weiser
>    = Larry Koved

>Lisp Flavors (which you mention below) is an example of a lanugage
>which has is a combination of object-oriented and non-object-oriented
>features in a single language.  Lisp is not object oriented, but the
>flavors package in lisp is object oriented.  I would not classify
>Lisp as an object oriented language;  only the flavors part is
>object oriented (to a degree).  I do not know of a language which
>only has inheritence, but not objects.

Lisp itself is object oriented in the sense that lisp variables
are not typed.  So, an operation like plus needs to check the types
of its arguments before it can execute.  That, of course, doesn't
give you everything you want in an object oriented language, but
I would like to make a couple other points.  One is that making
*every* procedure into a method (or operation) is probably not the
best approach.  There are still some routines that seem (at least
to me) to want to be just regular functions -- especially those
that don't have any arguments at all.  Now, I think that Smalltalk
does require all procedures to be operations attached to some
object; someone *might* be able to convince me this is wise, but
I'm not convinced yet and would like to see more development first.
My feelings here are connected to a basic feeling that when you're
adding new AI tools in lisp, they should be fully integrated with
other tools, etc, already available in lisp rather than making you use
the new AI tool in isolation from what was already in lisp.  (See my
paper on YAPS from AAAI-83 for another example of this.)

The second point is that there are hooks in flavors that allow
messages to be sent to any lisp object.

>The degrees of [of an object oriented language] are the degrees to which the
>language makes the sharp distinction about object manipulation.
>In particular, how well the language protects the objects, their
>internal representations and access to the procedures which manipulate
>the representation.

I'm not sure why you think the amount of protection the language
gives the object is that important...  I do think it is good to
have things set up somehow so it is clear how the objects of a
given type are to be handled by outside routines, but other aspects
of object oriented programming are much more important in my mind
(see the rest of this article!).

>> >The performance of the language (instructions
>> >per second) is a major consideration in deciding the degree to which
>> >a language's design is OO.  Being extremely OO is expensive in
>> >processing time and/or space.
>> 
>> Now this is an interesting issue.  Why should OO be expensive?
>> It need not be, because it need not be a runtime feature of a language.
>> Smalltalk is mostly interpreted, and so is slow for that reason,
>> not because it is OO.  The Maryland Flavors Package under Franz
>> Lisp allows compiled methods, flavors etc, and so runs not too
>> much slower than bare Lisp.  And a completely statically checked
>> and implemented OO language should be as fast as any other at runtime.

Our Maryland flavors package does allow methods, etc, to be compiled,
however, determining the appropriate method to use is a runtime
operation.  When a flavor is defined, every new flavor/message pair
is added to a hash table which is used to determine which method
should be used when an object is sent a message.  This makes run
time checking fast -- though not quite as fast as it would be in
a statically checked language.  But, to go to a statically checked
language, in my mind, would be to lose a lot of the nice features
of a flavors system (as I state at the beginning of this article!).

(One of the people here (Bob Bane) has extended flavors to allow
optional type declaration a new package for flavors objects so that
method determination can be done at compile time.  But, we view
that as strictly optional and probably only done once a system is
in a production phase.  Even then, of course, there would *have*
to be some run time checking since any flavor that might be used
as a mixin will need it.)

>> Might be slow to compile with current technology--but we haven't had
>> much practice at building fast OO compilers.

Combine time (or compile time) *is* slow in Maryland flavors.  But,
we win because run time execution is quite good.  I know of some
things that can be done to speed things up a bit, but it isn't
clear (yet) what the best approach really is.  The ideas I was
thinking about would tighten things up a bit in terms of programming
style and clarify (and restrict!) some things about using instance
variables to communicate between flavor and other flavors which
mix it in.  It's not clear that the restrictions involved are
appropriate -- indeed some of these ideas would probably make
inappropriate restrictions.  The question is whether we can figure
out what is appropriate and what is inappropriate and take advantage
of the appropriate ones to win at combine time.  As far as I'm
concerned, we need to understand that kind of communication far
better before I'm willing to put restrictions in.  (Besides, I
don't have the time!!!)

>Yes, the issue about performance of systems which require protecton
>is interesting.  If and when type checking can be done statically,
>the cost is much lower.  You make refrence to flavors.  The flavors
>part of lisp is object oriented, but the rest of lisp upon which
>flavors is implemented is not.  I suspect that this makes a difference.
>When looking a security (protection) oriented systems, there are costs
>incurred due to the protection mechanisms.  Once you start to do
>multi-programming, then you get many different types of protection
>problems which do not occur in uni-programming systems (and languages).
>This is also a factor in why protected systems incur a heavy cost
>at run-time.

Type checking in flavors pretty much winds up meaning simply that
an object can handle certain messages appropriately.  I've alluded
in the beginning of this article to some ways of doing this -- and
at compile (or combine) time.  Of course, the language can't
guarantee that you are using the appropriate mechanisms, but I
think the tradeoff here is worth it.

Things you can do:

- Organize your flavors into families when you have a set of flavors
  which will be used in similar situations by defining some common
  flavor which they will all mix in.  (Eg, when a connection from one
  object could lead to an object of any one of several flavors.)
- Define as many of the methods that the family is expected to handle
  in the common mixin flavor as is reasonable.  (This even saves
  work!)
- Declare all the other methods that the family is expected to handle
  as :required-methods of the common mixin flavor.
- Declare all the methods which a common mixin flavor needs to call
  as :required-methods.

Note that by declaring a method as a :required-method, the system
will complain if non-mixin flavors are created which do not define
the method.

Also, notice that there are (at least!) two kinds of communication
going on here (and this is probably why flavors doesn't distinguish
between internal and external methods):

	1. Between a flavor and outside routines via messages sent
	   to objects of that flavor (or objects that inherit methods
	   from that flavor).
	2. Between a flavor and flavors that mix this flavor in.  This
	   is done via messages sent to "self" by both the mixin
	   flavor and the flavor mixing it in.  It is also done via a
	   flavor referencing the instance variables of the mixin
	   flavor.

Is the latter external or internal?  It is external to the individual
flavors but may be internal to the family of flavors.  What is the
scope here?


I guess what I'm saying is that object oriented programming in
general and flavors in particular are great!  There are some areas
that could be worked on -- they could be made better -- but there
are some complicated issues here that need to be explored.  I could
easily see people addressing these by adding greater restrictions
to a system like flavors -- I would be very reluctant to do this.
*Some* restrictions are probably appropriate in the sense that they
clean up the communication between flavors.  But, at the same time
you don't want to "clean up" necessary avenues of communication --
a lot of the power of object oriented programming lies in its
flexibility.
-- 
				-Liz Allen

Univ of Maryland, College Park MD	
Usenet:   ...!seismo!umcp-cs!liz
Arpanet:  liz@tove (or liz@maryland)

"This is the message we have heard from him and declare to you:  God
 is light; in him there is no darkness at all" -- 1 John 1:5

rmc@panda.UUCP (R. Mark Chilenskas) (02/11/85)

	One article in the "quest for a definition of object oriented" 
requested an example of a type of inheritance which is not included in 
Smaltalk.  I think that the AI "knowledge representation languages" such 
as Pearl or Omega.  They provide inheritance of demons which are fired 
when the "status" of objects change (the whenever a new object of the 
class is created, when one is changed, when one is disposed of...)  
While this can probably be handled fairly simply by hacking class specific
New messages etc., it is not provided in the base ST80 language.

	I think that some articles are confusing the language ST80 with
the programming environment provided by Xerox to go with the language.
One could consider an improved Modula-2 programming environment where 
one could modify, recompile, and re-link the implementation module for
an object just as dynamically as one can in ST80.  It would require keeping
a procedure dictionary lying around so one could direct requests to the 
most recent copy of the method / implementation module, or linking 
implementation modules indirectly using a scheme similiar to the VMS runtime
system vectors.  I don't know if Lilith does this sort of thing or not, but
other Modula systems i have seen consider Modula just another Pascal-like
language.  ST80 feels more like a Lisp system becuase it has better 
program development support.  This is an implementation decision and is
not dictated by the language.

	I basically don't currently believe that a definition of what 
"object oriented language" means is currently possible.  We as computer 
scientists are still at the stage of pointing and saying ST80 is for sure
and BASIC is certainly not object oriented.  This is actually ok.  Maybe 
Mathematics makes definitions before there is a consensus in the community
about what words mean, but even that is debatable.  What we are doing now
is pointing and coming up with examples.  Eventually a consensus will 
arise, but by that time all the formal definition will be good for is 
introducing students to a concept which is well understood by the computer
science community as a whole.

	Enjoy,
					R Mark Chilenskas
					decvax!genrad!panda!rmc

cca@pur-phy.UUCP (Allen) (02/11/85)

I just can't resist any longer.  Here's a quote from Dan Ingalls
"Design Principles Behind Smalltalk" article in the August '81 Byte:

	"... Smalltalk provides a much cleaner solution:  it
	sends the name of the desired operation, along with any
	arguments, as a message ... with the understanding that
	the receiver knows best how to carry out the desired
	operation.  Instead of a bit-grinding processor raping
	and plundering data structures, we have a universe of
	well-behaved objects that courteously ask each other to
	carry out their various desires."

Alas, it's back to raping and plundering for me, lacking a Smalltalk
machine....

Charlie Allen		..pur-ee!pur-phy!cca

rcd@opus.UUCP (Dick Dunn) (02/14/85)

> I just can't resist any longer.  Here's a quote from Dan Ingalls
> "Design Principles Behind Smalltalk" article in the August '81 Byte:
> 
> 	"... Smalltalk provides a much cleaner solution:  it
> 	sends the name of the desired operation, along with any
> 	arguments, as a message ... with the understanding that
> 	the receiver knows best how to carry out the desired
> 	operation.
>...

The fundamental asymmetry between the object which does the sending and the
arguments (which are also objects) is a giant flaw in this model.

>	...Instead of a bit-grinding processor raping
> 	and plundering data structures, we have a universe of
> 	well-behaved objects that courteously ask each other to
> 	carry out their various desires."

Except that some of those objects bodily grab others (the arguments) and
cart them off to parts unknown, slaves in bondage to their nefarious
purposes.

If you can convince yourself that, in an expression such as "x+y", the
roles of x and y are FUNDAMENTALLY different--i.e., that x is active but y
is passive--then perhaps you can believe in Smalltalk.  I can't.
-- 
Dick Dunn	{hao,ucbvax,allegra}!nbires!rcd		(303)444-5710 x3086
   ...Cerebus for dictator!

vermeule@gumby.UUCP (02/26/85)

hdhdjhdJ
J
q

ZZ> I just can't resist any longer.  Here's a quote from Dan Ingalls
> > "Design Principles Behind Smalltalk" article in the August '81 Byte:
> > 
> > 	"... Smalltalk provides a much cleaner solution:  it
> > 	sends the name of the desired operation, along with any
> > 	arguments, as a message ... with the understanding that
> > 	the receiver knows best how to carry out the desired
> > 	operation.
> >...
> 
> The fundamental asymmetry between the object which does the sending and the
> arguments (which are also objects) is a giant flaw in this model.
> 
> >	...Instead of a bit-grinding processor raping
> > 	and plundering data structures, we have a universe of
> > 	well-behaved objects that courteously ask each other to
> > 	carry out their various desires."
> 
> Except that some of those objects bodily grab others (the arguments) and
> cart them off to parts unknown, slaves in bondage to their nefarious
> purposes.
> 
> If you can convince yourself that, in an expression such as "x+y", the
> roles of x and y are FUNDAMENTALLY different--i.e., that x is active but y
> is passive--then perhaps you can believe in Smalltalk.  I can't.
> -- 
> Dick Dunn	{hao,ucbvax,allegra}!nbires!rcd		(303)444-5710 x3086
>    ...Cerebus for dictator!

*** REPLACE THIS LINE WITH YOUR MESSAGE ***

jans@mako.UUCP (Jan Steinman) (03/02/85)

Dick Dunn writes:
> ... some of those objects bodily grab others (the arguments) and cart them
> off to parts unknown, slaves in bondage to their nefarious purposes.

Hold on there, Dick.  I don't think you really understand what's going on in
Smalltalk.  An object is in control of it's own private memory (known as
"instance variables") and doesn't get abused by other objects unless it agrees
to (implements a selector for) such abuse.

Also, (excepting UCB's latest implementation) only object *references* are
passed around as arguments.  An object can ask another object "what is your
value", "change your value to X", or even "destroy thyself", but the object
doesn't do damned thing (except report that it's confused by the request)
unless an appropriate response exists in it's protocol, or the protocol of
it's superclass chain.
-- 
:::::: Jan Steinman		Box 1000, MS 61-161	(w)503/685-2843 ::::::
:::::: tektronix!tekecs!jans	Wilsonville, OR 97070	(h)503/657-7703 ::::::