From: jm13@gte.com (Joseph D. Morrison)
Newsgroups: comp.object
Subject: Re: Class methods (was: Re: How to design a data structure library)
Date: 30 Jul 92 18:12:13 GMT
	<5618@vexpert.dbai.tuwien.ac.at>
	<GEOFF.92Jul27100601@wodehouse.flash.bellcore.com>
	<graham.712278529@galois>
Organization: GTE Laboratories, Waltham, Massachusetts, USA
In-reply-to: graham@maths.su.oz.au's message of 27 Jul 92 23:08:49 GMT

In article <graham.712278529@galois> graham@maths.su.oz.au (Graham Matthews) writes:

> Personally I think this is just awful. I want to write
>
>         c := a + b;		OR
>         c := a union b;
>
> Any other notation is completely non-suggestive.

I think we should worry about semantics first and syntax later.
Rather than worry about what code we should write to express
addition or union (a syntactic matter) we should be trying to
deal with semantic problems, such as how to express the concept
of addition given the inherent asymmetry of dispatching on only
the first argument.

I don't have any answers here, just some thoughts which I think
are relevant to this discussion.

First thought: it is a good idea to distinguish between mutable
and immutable objects.

Mutable objects are the ones in which identity corresponds with
allocation (i.e. you could imagine using the memory address as an
OID). Objects that we define using C++ classes, for example, are
mutable.  They have state which can change over time. Two
different mutable objects can have the same value.

Immutable objects are the ones in which identity corresponds with
VALUE. Semantically, two allocated immutable "objects" with the
same value are actually the same object. You could imagine an
implementation in which all possible immutable objects are
created before the program starts, and the constructor functions
for immutable objects always return one of the already-created
objects. Alternately, the constructor functions could always
allocate new hunks of memory (like mutable objects), but the
object identity comparison (i.e. EQ in lisp) would be modified so
that in the case of immutable objects it would do value
(byte-for-byte) comparison, rather than a pointer comparison.

In most OO systems, "objects" are always mutable, and integers
are immutable. In a functional programming language, all objects
are immutable.

As a final example to clarify things, one could imagine a mutable
set type MSET, and an immutable set type ISET.

You can say:

  a = MSET (43, 21, 100);
  b = MSET (43, 21, 100);

a and b are two different sets. We could then say:

  INSERT (a, 113);

This would MODIFY "a" to have a fourth element. "b" would be
unchanged. Then you could imagine:

  a = ISET (43, 21, 100);
  b = ISET (43, 21, 100);

a and b refer to the SAME SET OBJECT. What if you then say:

  INSERT (a, 113);

Well, this operation just doesn't make sense for an ISET.  For
ISETs, INSERT must be a FUNCTION which returns another ISET,
since there is no concept of "changing an object's value". So you
could say:

  a = INSERT (a, 113);

Now "a" refers to a DIFFERENT ISET OBJECT; the set (43, 21, 100,
113). If you then typed:

  b = INSERT (b, 113);

then b and a would once again refer to the same ISET object (43,
21, 100, 113). At this point, the expression EQ (a, b) would be
true. and so on...

So let's generalize the original discussion. Consider:

      a = b + c;

where b and c are of some immutable type, and "+" is defined to
compute a new value of that type.

The first observation is that we don't really need to worry about
whether "+" allocates memory. When the objects involved are
immutable, memory allocation becomes an implementation detail. In
fact, when all objects involved are immutable, we can talk about
"creating" an instance OR we can talk about "selecting" an
instance. Semantically it's kind of the same.
  
Note that this holds for integers. We can say that the +
operation "makes" a new integer or "selects" an integer.

Finally, note that it doesn't make sense to have an operation
like:

  b += c;

if b and c are immutable. Just like for integers, we don't want
to write:

  2 += 3;

it just wouldn't make sense!

Now consider "a = b + c" for mutable objects. *Now* we have to
decide, does "+" allocate a new object or not? There is no
"correct" answer to this; you simply have to decide. You can
imagine a function which takes two objects and allocates a third
one, or a different function which takes two objects and modifies
one of them. You can imagine a language which lets you define
either or both of these, then lets the application writer choose
which version she wants to use later on.

I'm not claiming to solve any deep problems in this discussion;
but I am attempting to point out that in this "a+b" question,
there are two completely different problems, depending on whether
we are dealing with mutable or immutable objects. So if we solve
the problem for integers, we haven't solved it for regular
classes, and vice versa.

Another thought on this discussion; "conventional" OO languages
dispatch on the first argument. If we therefore want to do away
with functions and make all operations "methods", we seem to be
stuck with an asymmetry which seems unnatural in operations such
as "+".

One solution (my favourite) is to use CLOS-type dispatching on
all the arguments. No more asymmetry. (Of course, all you
"encapsulation sympathizers" will be unhappy with this idea.)

But actually, I suspect that many people who are worried about
this "a+b" problem aren't even thinking about type dispatching. I
mean, say you know the types of "a" and "b" at compile time. You
still have this interface problem; do you write "a += b" or
"c = a + b" or what?

So to conclude, here's my suggestion: for immutable objects,
always write:

c = a + b;

(modulo colons, semicolons, parentheses, etc.)

For mutable objects, if "+" creates (allocates) a new object,
write the same expression:

c = a + b;

For mutable objects, if "+" does not create a new object, but
rather, modifies one of the argument objects, write:

a += b;

or its moral equivalent. Boy can I get long-winded :-)
Ok, my fire extinguisher is poised and ready...

        Joe Morrison
--
GTE Laboratories Incorporated         Email: jmorrison@gte.com
40 Sylvan Road                        Phone: (617) 466-2614
Waltham, Massachusetts, 02254
Newsgroups: comp.object