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
|