Object: Identity vs. Environment

Lothar Schenk lothar.schenk at gmx.de
Thu Jun 5 18:43:09 UTC 2003


Richard A. O'Keefe wrote:

>> Lothar Schenk <lothar.schenk at gmx.de> wrote:
>>	I agree with you in principle, but there is still something
>> 	wrong here.  Object has no business knowing anything about
>> 	Fooness, and so it shouldn't provide a method to test
>> 	specifically for Fooness, even if it is only lexically suggested
>> 	that it do so.
>
> I guess the fundamental issue is whether you believe
> that "Object has no business knowing anything about Fooness"
> is an absolute moral law or simply a practical guideline.

Do you mean if this is a religious issue with me? No, it isn't. Still I do 
think that principles can guide us in our design issues. People may differ, 
however, in the relative importance they give to certain principles over 
others.

> Myself, I'm not too fussed about #isFoo methods in Object
> because I think it's only a practical guideline, and I do
> not believe that the #isFoo methods in Object are doing enough
> harm to worry about.
>
> When Squeak gets some kind of "package" system so that
> (a) methods are labelled with the package they belong to and
> (b) packages have documentation strings you can view and
> (c) Browsers are aware of packages
> then I think it will be rather hard to argue that
> Object/Foo should not have an #isFoo method.
>
> Even now it is rather hard to argue this.
> Let's take "#isColor" as our example.
> It is really literally TRUE that most objects are not colours.
> Putting "isColor ^false" in Object has to be better than
> putting "isColor ^false" in hundreds if not thousands of
> other classes.  It's better for Object to "know" that most
> objects are not colours than for every one of *my* classes
> to have to "know" that most objects are not colours.

I didn't argue that this kind of checking doesn't belong in Object. I argued 
that we don't need an individual method for every set inclusion criterion, 
but only one generic method which takes the relevant set inclusion criterion 
as a parameter.

The generalization/specialization mechanism represented by inheritance 
suggests that we should have generic behavior higher up in the class 
hierarchy and specialized behavior lower down in the class hierarchy. In 
keeping with this I see the role of Object as providing _generic_ behavior 
for all objects, as opposed to seeing it merely as a repository of code you 
can use globally in the system.

You may compare my proposed #fulfills: method with the #respondsTo: method in 
Object, which is semantically similar, only narrower in its application 
context ("belongs to the set of objects which respond to #bar").

There we also don't have separate #respondsToFoo methods for every possible 
method an object could respond to.
 
>> 	It is nevertheless true that all objects should
>> 	have a generic method for checking if the particular instance in
>> 	question has Fooness, but not only specifically for Fooness, but
>> 	also for any other criterion of belonging to a particular set.
>>
>> 	The keyword here is parameterization.
>>
>> 	So why not do it this way:
>>
>> 	Object>>fulfills: aCriterion
>>             ^false
>>
>> 	Foo>>fulfills: aCriterion
>>             ^aCriterion = #Fooness
>>             "Note that one can just as well react to more than one
>>               criterion"
>>
>> 	Color>>fulfills: aCriterion
>>             ^aCriterion = #Colorness
>
> Coupling.  *Coupling*.  COUPLING!

Well, what about coupling, Richard?

Coupling is necessary to get anything useful done.

> _That's_ why not do it that way.

I guess the answer to this issue depends on whether you believe that 
"minimizing coupling" is an absolute moral law or simply a practical 
guideline.

>  You are telling me
> "don't have #isFoo and #isColor in Object,
>  have one method which does BOTH."

Weren't parameters invented to make such a thing possible?

> That is, to avoid a handful of harmless methods, you
> are proposing coupling unrelated methods on a large scale.

What kind of coupling are you talking about, how do these methods get coupled 
and why would this coupling be inappropriate?

These methods are not unrelated.

Methods like #isFoo, #isColor and #isWhatever can be considered to be 
semantically the same on the generic Object level. That they almost 
invariably begin with "is-" is also a give-away in this regard. Semantically, 
what all these various #isFoo methods do is to check for inclusion/exclusion 
of the object in question according to some set-defining criterion. That's 
exactly what my proposed #fulfills: method is designed to do in a generic 
way.

> The cure is worse than the disease.

So, you'd rather like to have #respondsToAt, #respondsToAtPut, 
#respondsToFirst, #respondsToLast and so on in Object, rather than have one 
parameterised generic #respondsTo?

>> 	This is similar to the case when I would ask you if you were a
>> 	Kroogleswank.  If you are not a Kroogleswank you needn't even
>> 	know what a Kroogleswank is to reply that you are not.
>
> Things are not that simple.  Suppose I ask you
> "He tangata a koe?"  (Art thou a "tangata"?)
> If you say "never heard of them, so I'll answer 'false'",
> you'd give the wrong answer.  ("tangata" = person, human being.)
>
> It's not enough to say "well, you can't be a tangata without
> KNOWING that you are a tangata", because that isn't really true.

What is your point? If you have implemented a method #isPerson to check for 
"Personness" than #isTatanga won't work either, even though this may be an 
equivalent way of denoting the same thing.

> You might have
>
>     Person>>
>         fulfills: aSymbol
>             ^#(personhood materiality heatfulness mobility
>                actorhood billability ......) includes: aSymbol
>
> which says nothing about being a tangata.  So what can I do to
> make your code work with mine?  That's right, add
>
>     isTangata
>         ^self fulfills: #personhood
>
> to Object.

LOL!

You seem to have blinded yourself to the obvious.

Person>>fulfills: aCriterion

^#(tatanga personhood ...etc...) includes: aCriterion

If I want instances of Person to respond both to #tatanga and #personhood as 
criteria for being a person, then why not put them in there right next to 
each other? If Person is the class responsible for defining what "personhood" 
means, than it should contain the code which defines it.

Of course, having two identifiers for the same concept raises the possibility 
of confusion; this was just to show that it's possible.

>  Why Object?  Well, Kzin and PiersonsPuppeteer might also
> claim to fulfill #personhood, without inheriting from Person.

And well they might do so:

Kzin>>fulfills: aCriterion

^(aCriterion = #personhood)

and, lo!, Kzin fulfills #personhood without having to inherit from Person.

>  Come
> to think of it, so would a Grog claim #personhood, without having
> #mobility, while Outsiders might lack #heatfulness.

Same solution.

>> 	So, your example above would be written the following way (using
>> #Colorness as the criterion for things which behave like colors):
>>
>> 	Color>> = aColor
>> 	    (aColor fulfills: #Colorness) ifFalse: [^false].
>> 	    ^aColor privateRGB = rbg and: [
>> 	     aColor privateAlpha = self privateAlpha]
>>
>> 	Apparently, this is no more complex than it was before,
>
> Actually, in my eyes it is significantly more complex than before.
>
>> 	but this version has the advantage that only those classes that
>> 	either provide or use (check for) Fooness need to know anything
>> 	about it, while Object itself never needs to know anything about
>> 	Fooness, Colorness or whatever, as it should be.
>
> You have forgotten inheritance.  Instead of simply writing
>
>     fulfills: aSymbol
>         ^aSymbol == #Colorness
>
> in Color, one would have to write
>
>     fulfills: aSymbol
>         ^aSymbol == #Colorness or: [super fulfills: aSymbol].

I do not see how this comes about. If #isColor in Color does not need the call 
to super, than fulfills: with parameter #Colorness should not need it either. 
Since both expressions are semantically equivalent, I would expect them to 
exhibit the same behavior in respect to inheritance.

> That is, every method which asserts that instances of a class have
> some property would be MORE complicated than the corresponding
> #isFoo method would have been.

As I said, I doubt this. Provide an example of two semantically equivalent 
cases, where the parameterised version necessarily must be more complicated 
than the unparameterised version.

[snip]

> Where we differ is, I imagine, in our judgement about whether
> #isBar methods in Object are such a great evil that even a complex
> coupled hack is more tolerable.

Then we would also differ in our judgement on having such a "nasty" complex 
coupled hack as #respondsTo: in Object, wouldn't we?

Or why would you accept parameterisation in one case, but not the other?

-- Lothar

"Walk this world with me"



More information about the Squeak-dev mailing list