Re: Clean Object Class Design -- Circle/Ellipse

From: Dave Harris <brangdon_at_cix.co.uk>
Date: Sun, 7 Oct 2001 15:23 +0100 (BST)
Message-ID: <memo.20011007152312.52627A_at_brangdon.madasafish.com>


bbadour_at_golden.net (Bob Badour) wrote (abridged):
> > A /variable/ is a computational entity that stores a single
> > reference (the /value/ of the variable) to an object.
>
> "reference to an object" implies that "object" is variable.

No, it doesn't.

> Values are self-identifying and one cannot reference a value.

This is confused - you are making it sound like a Smalltalk variable is a reference to a reference. It isn't, necessarily.

A variable is associated with two values: the value that it is, and the value that it has. The value that it is is its identity, what in concrete terms we might call its address. The value that it has is the contents of that address. We can store a number like 5 or we can store the address/identity of another variable. Thus saying a thing is referred to by a variable does not tell us whether it is a value or a variable. Or rather, it will always be a value but that value may or may not be the identity of a variable.

Incidently, I harp on about variables having two values because I think it helps clarify what is going on. Both values are immutable, but the attachment between them can change. Thus in an assignment like:

    a := 5.

the variable denoted by 'a' does not change - it keeps its identity, its address stays the same. Likewise 5 doesn't change either. What has changed is that a is now attached to 5. The /attachment/ changes.

> One can reference storage or memory that contains some representation
> of a value, but storage and memory are variable.

When we are doing that, the value attached to one variable is the identity of another variable. This identity is another value, immutable just like the value 5. Storing 5 into a variable and storing an address into a variable are much the same thing. In both cases we are changing the attachment between a variable and a value.

Think of it this way. If variables can only refer to other variables, never values, how do we get out of the infinite recursion? Well, maybe there are ways, but in practice it doesn't work like that. Instead, every variable is a reference to an immutable value. Some of those values are identities of variables and so have mutable attachments of their own.

(The words "identity" and "attachment" are more abstract than "address" and "store". There are many ways to implement the mapping between a variables two values.)

> If you had included a little more from the standard where it defines
> /message send/ and explains that "Each argument is a reference to an
> object",

This bit:

    A /message send/ causes execution of the currently active method     to be temporarily suspended and for program execution to     continue starting with the first expression of another method.     A message send directs a message to an object. The object is     called the /receiver/ of the message. A /message/ consists of     a method selector and a set of arguments. Each argument is a     reference to an object. When an object receives a message, the     method selector of the message is used to select the method     from the object's behavior that corresponds to the selector.     The method becomes the new locus of execution. Special processing     takes place if the receiver's behaviour does not include a method     corresponding to the message's selector.

> you would see that Smalltalk requires a variable in order to send
> a message.

No it doesn't. It says that the message arguments are references to objects, so the message arguments are variables, but the message receiver is an object, not a reference. I think you are either confusing the arguments with the receiver, or you are supposing again that variables can only refer to other variables. Or maybe you think the receiver of a message is part of the message.

Here's an example:

     5 max: 6.

This will end up in a method declared like:

    max: aNumber

Now, aNumber is a variable that will be attached to the value 6. It will be attached to different values in other calls. Clearly aNumber is a variable. However, this does not mean it is attached to a variable.

> In other words, Smalltalk only pretends to have values and requires
> one to store a representation of a value in a variable prior to
> doing anything.

Not true. Inside the method we use variables to refer to the argument objects, but the objects themselves can be values. In the method call we see naked values. 5 is not reference to an address.

I think I see what you are saying, though. I believe early Fortran worked like that. Smalltalk doesn't, not according to its definition nor in how it is implemented. At machine code level, the object 5 will likely be stored directly in a register. It will not be represented as an address.

For what its worth, other objects (such as LargeIntegers) will not be implemented so directly. They will be implemented as you describe - some memory set aside somewhere, and a pointer to that memory passed around. However, this is just an implementation issue, invisible to the programmer. Conceptually there is no storage, and there is no way for a Smalltalk programmer to get at it, modify it, or even tell whether two LargeIntegers with the same value are implemented at the same address. Conceptually there is no difference between a LargeInteger and a SmallInteger in this.

> > (The ANSI standard does not define "instance". It uses "object"
> > instead. Later it says that when an object does have state, it
> > represents it with special kind of variables called "instance
> > variables". In other words, an object is not a variable but an object
> > can contain variables.)
>
> How does one change part of something that cannot change?

I don't follow the question. My discussion of attachments may help. Alternatively, are you supposing that because some objects have state, all objects have state? An object which does not have state cannot be changed, by definition.

> > So sorry, but in Smalltalk the value 5 is an instance of the class
> > SmallInteger.
>
> Untrue. An instance of the class SmallInteger can contain a
> representation of the value 5

This is confused again. An instance of SmallInteger does not /contain/ a representation of 5, it /is/ a representation of 5. (I presume we are using the word "representation" here because everything in a computer is but a representation of the platonic ideals.)

Instances of SmallInteger do not have addresses, they cannot be assigned to, they do not have attachments. They have no identity other than their value, but that value can be referred to, or assigned to, variables.

> Yes, I agree that one can have operations on values. These are, of
> course, different from update operations on variables. Have you not
> seen me state that previously? Of course, the Smalltalk standard
> requires all implementations to operate only on variables.

Not true. The above #max: example shows an operation being applied to a value, not a variable. It was not an update operation, of course.

I am going to stop commenting now, because what follows is just repeating points already made.

I wonder if it would help to compare other languages, such as C++. In C++ 5 is an rvalue, meaning it does not have an address. It is not a variable. In Smalltalk it is the same.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,

      brangdon_at_cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ | And drunk the milk of Paradise." Received on Sun Oct 07 2001 - 16:23:50 CEST

Original text of this message