I don't know if this is a radical change in the semantics per se, but certainly the status quo ante was not inconsistent or incoherent and did not obviously require a change as I saw it. By having non-indexed objects share the trait with indexed objects of 0 size of responding the same way to each of these operations:
object size 0 object at: anyIndex error object replaceFrom: 0 (or copyFrom:to: for strings) to: -1 with: anyObject startingAt: 1
Doesn't seem to lead to any singularities in semantics, and has some nice properties of making certain typechecking unnecessary in practice. The downside, of course, is that errors in reasoning may not be caught unless there *is* an error.
One possible singularity is that SmallIntegers do not continuously scale from their indexable Large Integer counterparts. (A two-chunk SmallInteger arguably should have a non-zero size, and perhaps even respond to at: in a manner that would be logically consistent with LargeIntegers that might represent the small numbers). For example:
10000000000000 size is 6, and (10000000000000 / 1000) size is 5, but (10000000000000 / 10000) size is 0!
Is it the latter issue, or some subtle performance issue that is driving this change?
-----Original Message----- From: MIME :duane@cmu.edu Sent: Wednesday, March 31, 1999 11:16 AM To: squeak@cs.uiuc.edu Subject: Re: 22 new updates
At 7:29 Uhr -0800 30.03.1999, Dan Ingalls wrote:
123 size no longer responds with 0. nil size no longer responds with 0.
That seems like a radical change in the semantics. Size seems to be everywhere defined to be the number of indexable variables in the receiver; so 0 seems like that right answer for objects that have no indexable variables.
<< File: ENVELOPE.TXT >>
One possible singularity is that SmallIntegers do not continuously scale from their indexable Large Integer counterparts. (A two-chunk SmallInteger arguably should have a non-zero size, and perhaps even respond to at: in a manner that would be logically consistent with LargeIntegers that might represent the small numbers). For example:
10000000000000 size is 6, and (10000000000000 / 1000) size is 5, but (10000000000000 / 10000) size is 0!
Is it the latter issue, or some subtle performance issue that is driving this change?
A slight follow-up on my previous message. Many of the earlier objections to reducing the range of size to exclude "scalar" operators was the inconvenience of having to provide express tests for nil, since nil no longer responds thereto. This raised some interesting issues, which I have yet to sort out.
nil is the sole instance of a class called UndefinedObject. This is an interesting characterization, since the name suggests that, perhaps except for operations such as "=", "==" and the related "isNil", "ifNil" and "ifNotNil," that nil should respond to nothing at all.
But it isn't so. nil *is* an instance of Object, after all, and does respond to a number of Object-related messages, in particular: "hash," "isLiteral," "fullPrintString," (even clone, although it just returns self).
So, nil as a truly undefined object has no pure, sacrosanct, theoretical definition, akin to the "bottom" of a denotational semantics. Or does it? Have we compromised its meaning as an undefined object over the years in the interest of producing a "practical" system, or just lapsed from time to time, and perpetuated the lapses for conveniences precisely of the kinds we saw when beloved "size" was removed from the list of "special" message to which the sole UndefinedObject would give meaning?
And, as to those objections, does the lack of purity of nil suggest that an Undefined object may not be what we need for our most "special" object? In particular, is it possible that instead of an UndefinedObject, what is really needed is an EverywhereDefinedObject, a construct, call it "top" or maybe "superSelf", which responds to each and every message sent to it with, say, itself?
Given my relative newbieness in Smalltalk, and the high caliber of computer scientists practicing in this area, I'll presume this has been considered and analyzed before before sticking my neck out much further, but I'd be curious for pointers on the subject.
In particular, is there a simple, definitive notion of what nil *is* (or is not), that would answer the question definitively whether or not it should respond to size? (It would seem, if there were, there are examples of other "lapses" that can be found simply by examining UndefinedObject.) Has the idea of "top" been previously considered?
[snip]
But it isn't so. nil *is* an instance of Object, after all, and does respond to a number of Object-related messages, in particular: "hash," "isLiteral," "fullPrintString," (even clone, although it just returns self).
So, nil as a truly undefined object has no pure, sacrosanct, theoretical definition, akin to the "bottom" of a denotational semantics. Or does it? Have we compromised its meaning as an undefined object over the years in the interest of producing a "practical" system, or just lapsed from time to time, and perpetuated the lapses for conveniences precisely of the kinds we saw when beloved "size" was removed from the list of "special" message to which the sole UndefinedObject would give meaning?
And, as to those objections, does the lack of purity of nil suggest that an Undefined object may not be what we need for our most "special" object? In particular, is it possible that instead of an UndefinedObject, what is really needed is an EverywhereDefinedObject, a construct, call it "top" or maybe "superSelf", which responds to each and every message sent to it with, say, itself?
Yes, I've often had similar thoughts. UndefinedObject seems self-contradictory. nil is the singleton of UndefinedObject, a descendant of Object, and is therefore a fully defined object in the hard sense (an object as chunk of bytes in memory), but represents the *concept of an undefined object. This is an unfortunate clash of hard and soft object realities, and is an example of the delicate self-deception that is everywhere in natural language.
That said, I don't see an especially pleasing alternative. Perhaps class Nothing would be more appropriate, but it really has essentially the same I'm-lying-to-myself-but-I-can-do-my-work-this-way quality. Then there is Any whose singleton nil could do anything in response to any message, but this would create confusion to justify a more flexible, "whatever I need for convenient programming" method response pattern. How about Nil and its singleton nil? This is just the computerese version of the more general Nothing, which I actually preferred.
Somehow, I suspect that none of the above actually helps. :)
Given my relative newbieness in Smalltalk, and the high caliber of computer scientists practicing in this area, I'll presume this has been considered and analyzed before before sticking my neck out much further, but I'd be curious for pointers on the subject.
In particular, is there a simple, definitive notion of what nil *is* (or is not), that would answer the question definitively whether or not it should respond to size? (It would seem, if there were, there are examples of other "lapses" that can be found simply by examining UndefinedObject.) Has the idea of "top" been previously considered?
I think the new, stricter size-semantic revolves around the idea that: you can only determine the size of an object that has size; size is a countable quantity; and counting begins with one. Zero is not a count, but our culture is very comfortable with the idea because it pervades our math, physics, and finance, and because more of us are programming computers these days. (Zero, as an invention, was an unecessary mistake. Don't bug me about that; it would lead to far... :))
I like the stricter semantic, and I'm willing to code the extra checks for nil.
Cheers.
Hi.
One possible singularity is that SmallIntegers do not continuously scale from their indexable Large Integer counterparts. 10000000000000 size is 6, and (10000000000000 / 1000) size is 5, but (10000000000000 / 10000) size is 0!
I think the problem here is not with size, but with one expects anInteger to answer. In mathematics, anInteger size... size of what? Amount of digits, but in what base? There's no such idea of "anInteger size"...
The other example is sending ln to 0.0... I believe that the final fix for #raisedTo: doesn't send ln to 0.0 anymore. But before that, I remember reading how several libraries gave a full range of different messages and errors and flags and stuff when that happened and in the evaluation of 0.0 raisedTo: 0.75. I really disliked the whole thing since after all,
LOGARITHM OF ZERO IS NOT DEFINED!
So why in heavens sending ln to 0.0... it's not correct! But ok, if one builds a library with, hmmmmm... suitable algorithms and conventions and bit buckets so that anyway the answer is zero... it's so Microsoftish...
Just my feelings about it, eh? :))).
Andres.
squeak-dev@lists.squeakfoundation.org