Object>>#is:? (was: Re: PackageDependencyTest)

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
71 messages Options
1234
Reply | Threaded
Open this post in threaded view
|

Object>>#is:? (was: Re: PackageDependencyTest)

Chris Muller-3
Andreas wrote:

>        (foo isKindOf: FooBarMorph) ifTrue:[...]
>
> is completely pointless. If you're writing this already, you might as well
> avoid that dependency and write:
>
>        (foo is: #FooBarMorph) ifTrue:[...]
>
> etc. I'd really like to see #is: integrated so that it can used
> interchangeably with #isKindOf: but using the name instead of the type.

That would be a great method for helping to avoid hard dependencies.
My only suggestion would be for us to consider the namespace.  It
might be a shame to consume beautifully terse #is: for something as
mundane as a package-existence / type-check.

Applications might already, or want to, use #is:.  However, any
overrides of #is: will rob them of the functionality provided by
Object>>#is:, so a complication is introduced, a choice is forced.

Ok, I might be wrong in a practical-sense about this, since the
package-existence check would typically be on a PackageInfo object or
something that probably wouldn't otherwise need #is:.

My only point is that, we should remember to duly consider the
namespace when consuming a selector as grand as #is: in case it might
be better-appreciated in the application namespace..

Regards,
  Chris

Reply | Threaded
Open this post in threaded view
|

Re: Object>>#is:? (was: Re: PackageDependencyTest)

Andreas.Raab
For discussion, this is what I'm suggesting:

Object>>is: aSymbol

        "A generic membership test. Should be used to avoid the proliferation
of isXXX
        methods where appropriate. Use it like here:

                FooBar>>is: aSymbol
                        ^aSymbol == #Foo or:[aSymbol == #Bar or:[super is: aSymbol]]

        This implementation can also be used with class names to replace the usage
        of aMorph isKindOf: SketchEditorMorph with, e.g.,  aMorph is:
#SketchEditorMorph
        to avoid unnecessary dependencies on classes"

        "Check to see if aSymbol is a class name in the receiver's environment"
        self class environment
                        at: aSymbol
                        ifPresent:[:aClass| ^self isKindOf: aClass].

        ^false


On 3/4/2010 10:50 AM, Chris Muller wrote:

> Andreas wrote:
>
>>         (foo isKindOf: FooBarMorph) ifTrue:[...]
>>
>> is completely pointless. If you're writing this already, you might as well
>> avoid that dependency and write:
>>
>>         (foo is: #FooBarMorph) ifTrue:[...]
>>
>> etc. I'd really like to see #is: integrated so that it can used
>> interchangeably with #isKindOf: but using the name instead of the type.
>
> That would be a great method for helping to avoid hard dependencies.
> My only suggestion would be for us to consider the namespace.  It
> might be a shame to consume beautifully terse #is: for something as
> mundane as a package-existence / type-check.
>
> Applications might already, or want to, use #is:.  However, any
> overrides of #is: will rob them of the functionality provided by
> Object>>#is:, so a complication is introduced, a choice is forced.
>
> Ok, I might be wrong in a practical-sense about this, since the
> package-existence check would typically be on a PackageInfo object or
> something that probably wouldn't otherwise need #is:.
>
> My only point is that, we should remember to duly consider the
> namespace when consuming a selector as grand as #is: in case it might
> be better-appreciated in the application namespace..
>
> Regards,
>    Chris
>
>


Reply | Threaded
Open this post in threaded view
|

Re: Object>>#is:? (was: Re: PackageDependencyTest)

Michael Haupt-3
Hi,

Am 04.03.2010 um 19:58 schrieb Andreas Raab <[hidden email]>:

> For discussion, this is what I'm suggesting:
>
> Object>>is: aSymbol
>
>    "A generic membership test. Should be used to avoid the  
> proliferation of isXXX
>    methods where appropriate. Use it like here:
>
>        FooBar>>is: aSymbol
>            ^aSymbol == #Foo or:[aSymbol == #Bar or:[super is:  
> aSymbol]]
>
>    This implementation can also be used with class names to replace  
> the usage
>    of aMorph isKindOf: SketchEditorMorph with, e.g.,  aMorph is:  
> #SketchEditorMorph
>    to avoid unnecessary dependencies on classes"
>
>    "Check to see if aSymbol is a class name in the receiver's  
> environment"
>    self class environment
>            at: aSymbol
>            ifPresent:[:aClass| ^self isKindOf: aClass].
>
>    ^false

I like it.

We've frequently had hard times explaining to students why monkey  
patching is (used to be?) somewhat idiomatic in Squeak. Good to have  
this, it does away with one particular awkwardness and thus makes  
Squeak a little bit easier to grasp.

Best,

Michael

Reply | Threaded
Open this post in threaded view
|

Re: Object>>#is:? (was: Re: PackageDependencyTest)

keith1y
In reply to this post by Andreas.Raab
Another way of doing this, (last seen in SmalltalkAgents) is to  
implement askFor:

anObject askFor: #isMorph.

We had an ongoing debate on mantis as to whether this should return  
nil or false by default. (I prefer false, my more purist friends  
appear to prefer nil) if the selector is not implemented. I would  
favour this approach because askFor: is useful for other purposes, and  
in a world where things are more modular and less tightly coupled, it  
can be useful to have askFor: and askFor: aSelector ifAbsent:

Keith



so that the traditional isXX selectors still work, but

> For discussion, this is what I'm suggesting:
>
> Object>>is: aSymbol
>
> "A generic membership test. Should be used to avoid the  
> proliferation of isXXX
> methods where appropriate. Use it like here:
>
> FooBar>>is: aSymbol
> ^aSymbol == #Foo or:[aSymbol == #Bar or:[super is: aSymbol]]
>
> This implementation can also be used with class names to replace  
> the usage
> of aMorph isKindOf: SketchEditorMorph with, e.g.,  aMorph is:  
> #SketchEditorMorph
> to avoid unnecessary dependencies on classes"
>
> "Check to see if aSymbol is a class name in the receiver's  
> environment"
> self class environment
> at: aSymbol
> ifPresent:[:aClass| ^self isKindOf: aClass].
>
> ^false
>
>
> On 3/4/2010 10:50 AM, Chris Muller wrote:
>> Andreas wrote:
>>
>>>        (foo isKindOf: FooBarMorph) ifTrue:[...]
>>>
>>> is completely pointless. If you're writing this already, you might  
>>> as well
>>> avoid that dependency and write:
>>>
>>>        (foo is: #FooBarMorph) ifTrue:[...]
>>>
>>> etc. I'd really like to see #is: integrated so that it can used
>>> interchangeably with #isKindOf: but using the name instead of the  
>>> type.
>>
>> That would be a great method for helping to avoid hard dependencies.
>> My only suggestion would be for us to consider the namespace.  It
>> might be a shame to consume beautifully terse #is: for something as
>> mundane as a package-existence / type-check.
>>
>> Applications might already, or want to, use #is:.  However, any
>> overrides of #is: will rob them of the functionality provided by
>> Object>>#is:, so a complication is introduced, a choice is forced.
>>
>> Ok, I might be wrong in a practical-sense about this, since the
>> package-existence check would typically be on a PackageInfo object or
>> something that probably wouldn't otherwise need #is:.
>>
>> My only point is that, we should remember to duly consider the
>> namespace when consuming a selector as grand as #is: in case it might
>> be better-appreciated in the application namespace..
>>
>> Regards,
>>   Chris
>>
>>
>
>


Reply | Threaded
Open this post in threaded view
|

Re: Object>>#is:? (was: Re: PackageDependencyTest)

Stéphane Rollandin
In reply to this post by Andreas.Raab
I don't see how #is: can work in the large.

suppose I need test selectors like isMorph, isBorderedMorph, isMyMorph
and isMySpecializedMorph

every Morph must have

is: aSymbol
        aSymbol == #Morph ifTrue: [^ true].
        ^ false

then BorderedMorph must implement

is: aSymbol
        (super is: aSymbol
                or: [aSymbol == #BorderedMorph]) ifTrue: [^ true].
        ^ false

now MyMorph (supposedly a BorderedMorph) has

is: aSymbol
        (super is: aSymbol
                or: [aSymbol == #MyMorph]) ifTrue: [^ true].
        ^ false


so far so good, although at the moment all this code would be replaced with

isMorph
        ^ false

isBorderedMorph
        ^ false

isMyMorph
        ^ false

in Object, and the corresponding


isMorph
        ^ true

isBorderedMorph
        ^ true

isMyMorph
        ^ true

at the proper places


let's now consider MySpecializedMorph, a subclass of MyMorph that I *do
not* want to be considered as MyMorph:

is: aSymbol
        (super is: aSymbol and: [aSymbol =~ #MyMorph])
                or: [aSymbol == #MySpecializedMorph]) ifTrue: [^ true].
        ^ false

see the problem ?

I have to be aware of the behavior of each implementation of #is: in the
upward inheritance chain if I want to produce the proper tests. Going
down, those tests will become more and more complex and hard to grok.
Plus, reimplementing any of the #is: can possibly break any of the #is:
in subclasses. So all #is: implementations in a given hierarchy are
actually dependent. It's pure spaghetti code, as far away from OOP as it
gets.

I guess I'm missing something. how is this supposed to work ?


Stef




Reply | Threaded
Open this post in threaded view
|

Re: Object>>#is:? (was: Re: PackageDependencyTest)

Bert Freudenberg
In reply to this post by keith1y
On 04.03.2010, at 20:38, keith wrote:
>
> Another way of doing this, (last seen in SmalltalkAgents) is to implement askFor:
>
> anObject askFor: #isMorph.
>
> We had an ongoing debate on mantis as to whether this should return nil or false by default. (I prefer false, my more purist friends appear to prefer nil) if the selector is not implemented. I would favour this approach because askFor: is useful for other purposes, and in a world where things are more modular and less tightly coupled, it can be useful to have askFor: and askFor: aSelector ifAbsent:
>
> Keith

Wouldn't that be more aptly named perform:ifAbsent: ?

- Bert -



Reply | Threaded
Open this post in threaded view
|

Re: Object>>#is:? (was: Re: PackageDependencyTest)

Michael Haupt-3
In reply to this post by Stéphane Rollandin
Stéphane,

Am 04.03.2010 um 20:44 schrieb Stéphane Rollandin <[hidden email]
t>:
> I don't see how #is: can work in the large.

doesn't the implementation in Object do what you intend? (??)

> I guess I'm missing something. how is this supposed to work ?

... or am I missing something?

Best,
>

Michael
Reply | Threaded
Open this post in threaded view
|

Re: Object>>#is:? (was: Re: PackageDependencyTest)

Igor Stasenko
In reply to this post by Stéphane Rollandin
2010/3/4 Stéphane Rollandin <[hidden email]>:

> I don't see how #is: can work in the large.
>
> suppose I need test selectors like isMorph, isBorderedMorph, isMyMorph and
> isMySpecializedMorph
>
> every Morph must have
>
> is: aSymbol
>        aSymbol == #Morph ifTrue: [^ true].
>        ^ false
>
it much not. If you seen a proposed implementation, you don't need to
have such override, since
a base method will behave exactly like that for any Morph instance.

> then BorderedMorph must implement
>
> is: aSymbol
>        (super is: aSymbol
>                or: [aSymbol == #BorderedMorph]) ifTrue: [^ true].
>        ^ false
>
same as above. You don't need to override it.

> now MyMorph (supposedly a BorderedMorph) has
>
> is: aSymbol
>        (super is: aSymbol
>                or: [aSymbol == #MyMorph]) ifTrue: [^ true].
>        ^ false
>
>
> so far so good, although at the moment all this code would be replaced with
>
> isMorph
>        ^ false
>
> isBorderedMorph
>        ^ false
>
> isMyMorph
>        ^ false
>
> in Object, and the corresponding
>
>
> isMorph
>        ^ true
>
> isBorderedMorph
>        ^ true
>
> isMyMorph
>        ^ true
>
> at the proper places
>
>
> let's now consider MySpecializedMorph, a subclass of MyMorph that I *do not*
> want to be considered as MyMorph:
>
> is: aSymbol
>        (super is: aSymbol and: [aSymbol =~ #MyMorph])
>                or: [aSymbol == #MySpecializedMorph]) ifTrue: [^ true].
>        ^ false
>
> see the problem ?
>

A subclass inherits all aspects of parent class.
Think how many things you will need to override, if you would want to
subclass from a Number but don't behave like number.
Obviously, in your example you showing how to not abuse inheritance.
And its nothing to do with #is: method :)

> I have to be aware of the behavior of each implementation of #is: in the
> upward inheritance chain if I want to produce the proper tests. Going down,
> those tests will become more and more complex and hard to grok. Plus,
> reimplementing any of the #is: can possibly break any of the #is: in
> subclasses. So all #is: implementations in a given hierarchy are actually
> dependent. It's pure spaghetti code, as far away from OOP as it gets.
>
> I guess I'm missing something. how is this supposed to work ?
>
I think you should read mail archives.
First it was discussed about year ago (if i remember correctly).
Then Juan added it into Cius, cleaning a lot of isXXX method.
I think, we can ask Juan, how he feels about it, because he's the only
one who employed this idea so far.

>
> Stef
>


--
Best regards,
Igor Stasenko AKA sig.

Reply | Threaded
Open this post in threaded view
|

Re: Object>>#is:? (was: Re: PackageDependencyTest)

Igor Stasenko
On 4 March 2010 22:08, Igor Stasenko <[hidden email]> wrote:

> 2010/3/4 Stéphane Rollandin <[hidden email]>:
>> I don't see how #is: can work in the large.
>>
>> suppose I need test selectors like isMorph, isBorderedMorph, isMyMorph and
>> isMySpecializedMorph
>>
>> every Morph must have
>>
>> is: aSymbol
>>        aSymbol == #Morph ifTrue: [^ true].
>>        ^ false
>>
> it much not. If you seen a proposed implementation, you don't need to
> have such override, since
> a base method will behave exactly like that for any Morph instance.
>
>> then BorderedMorph must implement
>>
>> is: aSymbol
>>        (super is: aSymbol
>>                or: [aSymbol == #BorderedMorph]) ifTrue: [^ true].
>>        ^ false
>>
> same as above. You don't need to override it.
>
>> now MyMorph (supposedly a BorderedMorph) has
>>
>> is: aSymbol
>>        (super is: aSymbol
>>                or: [aSymbol == #MyMorph]) ifTrue: [^ true].
>>        ^ false
>>
>>
>> so far so good, although at the moment all this code would be replaced with
>>
>> isMorph
>>        ^ false
>>
>> isBorderedMorph
>>        ^ false
>>
>> isMyMorph
>>        ^ false
>>
>> in Object, and the corresponding
>>
>>
>> isMorph
>>        ^ true
>>
>> isBorderedMorph
>>        ^ true
>>
>> isMyMorph
>>        ^ true
>>
>> at the proper places
>>
>>
>> let's now consider MySpecializedMorph, a subclass of MyMorph that I *do not*
>> want to be considered as MyMorph:
>>
>> is: aSymbol
>>        (super is: aSymbol and: [aSymbol =~ #MyMorph])
>>                or: [aSymbol == #MySpecializedMorph]) ifTrue: [^ true].
>>        ^ false
>>
>> see the problem ?
>>
>
> A subclass inherits all aspects of parent class.
> Think how many things you will need to override, if you would want to
> subclass from a Number but don't behave like number.
> Obviously, in your example you showing how to not abuse inheritance.

or hot to abuse it.. whatever.
I meant: in your example you having a problems not because of #is:
method, but because of abuse of inheritance.

> And its nothing to do with #is: method :)
>
>> I have to be aware of the behavior of each implementation of #is: in the
>> upward inheritance chain if I want to produce the proper tests. Going down,
>> those tests will become more and more complex and hard to grok. Plus,
>> reimplementing any of the #is: can possibly break any of the #is: in
>> subclasses. So all #is: implementations in a given hierarchy are actually
>> dependent. It's pure spaghetti code, as far away from OOP as it gets.
>>
>> I guess I'm missing something. how is this supposed to work ?
>>
> I think you should read mail archives.
> First it was discussed about year ago (if i remember correctly).
> Then Juan added it into Cius, cleaning a lot of isXXX method.
> I think, we can ask Juan, how he feels about it, because he's the only
> one who employed this idea so far.
>
>>
>> Stef
>>
>
>
> --
> Best regards,
> Igor Stasenko AKA sig.
>



--
Best regards,
Igor Stasenko AKA sig.

Reply | Threaded
Open this post in threaded view
|

Re: Object>>#is:? (was: Re: PackageDependencyTest)

Stéphane Rollandin
In reply to this post by Igor Stasenko
> A subclass inherits all aspects of parent class.
> Think how many things you will need to override, if you would want to
> subclass from a Number but don't behave like number.

If #is: implementation has to reflect a class hierarchy, then I don't
see how it can be any better than #isKindOf: and #isMemberOf:

> Obviously, in your example you showing how to not abuse inheritance.

My example is based on real, actual code. I use quite a feww isXXX
methods to ask objects about a property or a protocol they may or not
have. It works fine and allows me to control fine discriminations along
the inheritance. That's not abusing, that's designing.

> And its nothing to do with #is: method :)

Yes, because #isXXX messages are quite special methods: they mostly
return mere ^true or ^false. So we are talking in this specific case
about replacing a simple modular, orthogonal set of clear
implementations with something much more complex and messy.

>
>> I have to be aware of the behavior of each implementation of #is: in the
>> upward inheritance chain if I want to produce the proper tests. Going down,
>> those tests will become more and more complex and hard to grok. Plus,
>> reimplementing any of the #is: can possibly break any of the #is: in
>> subclasses. So all #is: implementations in a given hierarchy are actually
>> dependent. It's pure spaghetti code, as far away from OOP as it gets.
>>
>> I guess I'm missing something. how is this supposed to work ?
>>
> I think you should read mail archives.
 > First it was discussed about year ago (if i remember correctly).

I did read the #is: proposal, at the time. No message that I remember
addressed the kind of problem I expose above and that I had already in
mind (although I did not participate in the discussion).

Now I would appreciate a simple answer about what's wrong in my example;
if there is confusion at this level, the #is: idea is certainly not as
straightforward as it may seem.

> Then Juan added it into Cius, cleaning a lot of isXXX method.
> I think, we can ask Juan, how he feels about it, because he's the only
> one who employed this idea so far.

So it may be only a nice idea untested in a real situation. I am very
dubious about its actual value; for one thing, it certainly cannot
replace the isXXX I use in my own code.

regards,

Stef





Reply | Threaded
Open this post in threaded view
|

Re: Object>>#is:? (was: Re: PackageDependencyTest)

Juan Vuletich-4
In reply to this post by Andreas.Raab
Andreas Raab wrote:

> For discussion, this is what I'm suggesting:
>
> Object>>is: aSymbol
>
>     "A generic membership test. Should be used to avoid the
> proliferation of isXXX
>     methods where appropriate. Use it like here:
>
>         FooBar>>is: aSymbol
>             ^aSymbol == #Foo or:[aSymbol == #Bar or:[super is: aSymbol]]
>
>     This implementation can also be used with class names to replace
> the usage
>     of aMorph isKindOf: SketchEditorMorph with, e.g.,  aMorph is:
> #SketchEditorMorph
>     to avoid unnecessary dependencies on classes"
>
>     "Check to see if aSymbol is a class name in the receiver's
> environment"
>     self class environment
>             at: aSymbol
>             ifPresent:[:aClass| ^self isKindOf: aClass].
>
>     ^false

I believe #isKindOf: is really bad. Reasons for this are given in
http://userweb.cs.utexas.edu/~wcook/Drafts/2009/essay.pdf . This was
also discussed here, you can google for the name of the pdf in the archives.

In the Cuis implementation of Object>>#is: there is no call to
#isKindOf:. The idea is to ask for a protocol, not for inheritance.

Cheers,
Juan Vuletich

Reply | Threaded
Open this post in threaded view
|

Re: Object>>#is:? (was: Re: PackageDependencyTest)

Juan Vuletich-4
In reply to this post by Igor Stasenko
Igor Stasenko wrote:
> ...
> Then Juan added it into Cius, cleaning a lot of isXXX method.
> I think, we can ask Juan, how he feels about it, because he's the only
> one who employed this idea so far.

I love it. It helps remove a lot of methods in base classes like Object
and Morph that don't really belong there.

Please note that in Cuis, #is: does not call #isKindOf:. All
implementors are explicit. This also means that you can see the
protocols an object conforms by reading the inheritance of the #is: method.

Cheers,
Juan Vuletich

Reply | Threaded
Open this post in threaded view
|

Re: Object>>#is:? (was: Re: PackageDependencyTest)

Michael Haupt-3
In reply to this post by Stéphane Rollandin
Stéphane,

2010/3/4 Stéphane Rollandin <[hidden email]>:
> If #is: implementation has to reflect a class hierarchy, then I don't see
> how it can be any better than #isKindOf: and #isMemberOf:

#isKindOf: accepts a Class, while #is: accepts a Symbol. Helps decoupling.

> Yes, because #isXXX messages are quite special methods: they mostly return
> mere ^true or ^false. So we are talking in this specific case about
> replacing a simple modular, orthogonal set of clear implementations with
> something much more complex and messy.

I really fail to see how #is: is complex and messy. Really.

> Now I would appreciate a simple answer about what's wrong in my example; if
> there is confusion at this level, the #is: idea is certainly not as
> straightforward as it may seem.

All right, I will take another look at it. I must have missed something. :-)

Best,

Michael

Reply | Threaded
Open this post in threaded view
|

Re: Object>>#is:? (was: Re: PackageDependencyTest)

Juan Vuletich-4
In reply to this post by Stéphane Rollandin
Stéphane Rollandin wrote:

>
> ...
> let's now consider MySpecializedMorph, a subclass of MyMorph that I
> *do not* want to be considered as MyMorph:
>
> is: aSymbol
>     (super is: aSymbol and: [aSymbol =~ #MyMorph])
>         or: [aSymbol == #MySpecializedMorph]) ifTrue: [^ true].
>     ^ false
>
> see the problem ?

Yes, I see it. As I see it, #is: is for asking about conformance to a
certain protocol. And your MySpecializedMorph does know what protocols
it conforms. So it can implement something like:

is: aSymbol
    aSymbol == #Morph ifTrue: [^true].
    aSymbol == #MySpecializedMorph ifTrue: [^true].
    ^false

without calling super. Please not that in Cuis, #is: does not call
#isKindOf: at all.

Cheers,
Juan Vuletich

> I have to be aware of the behavior of each implementation of #is: in
> the upward inheritance chain if I want to produce the proper tests.
> Going down, those tests will become more and more complex and hard to
> grok. Plus, reimplementing any of the #is: can possibly break any of
> the #is: in subclasses. So all #is: implementations in a given
> hierarchy are actually dependent. It's pure spaghetti code, as far
> away from OOP as it gets.
>
> I guess I'm missing something. how is this supposed to work ?
>
> Stef

Reply | Threaded
Open this post in threaded view
|

Re: Object>>#is:? (was: Re: PackageDependencyTest)

Stéphane Rollandin
In reply to this post by Juan Vuletich-4
so how do you handle the kind of problem I submitted ?

Stef



Reply | Threaded
Open this post in threaded view
|

Re: Object>>#is:? (was: Re: PackageDependencyTest)

Juan Vuletich-4
In reply to this post by Stéphane Rollandin
Stéphane Rollandin wrote:
>> ...
> If #is: implementation has to reflect a class hierarchy, then I don't
> see how it can be any better than #isKindOf: and #isMemberOf:

In my opinion, it does not have to reflect a class hierarchy at all, but
conformance to some protocol. Take a look at
http://userweb.cs.utexas.edu/~wcook/Drafts/2009/essay.pdf .

Cheers,
Juan Vuletich

Reply | Threaded
Open this post in threaded view
|

Re: Object>>#is:? (was: Re: PackageDependencyTest)

Michael Haupt-3
In reply to this post by Stéphane Rollandin
Hi again,

2010/3/4 Stéphane Rollandin <[hidden email]>:
> so how do you handle the kind of problem I submitted ?

all right, I just looked at your problem once more, and believe it's
abusive. An inheritance that is not an is-a relationship induces
physical pain in this simple me. :-) So I guess the problem is
actually somewhere else.

Best,

Michael

Reply | Threaded
Open this post in threaded view
|

Re: Object>>#is:? (was: Re: PackageDependencyTest)

Juan Vuletich-4
In reply to this post by Stéphane Rollandin
Stéphane Rollandin wrote:
> so how do you handle the kind of problem I submitted ?
>
> Stef
>
Had already answered to your original message, just a couple of minutes
before this. Please check it.

Cheers,
Juan Vuletich

Reply | Threaded
Open this post in threaded view
|

Re: Object>>#is:? (was: Re: PackageDependencyTest)

Stéphane Rollandin
In reply to this post by Michael Haupt-3
> I really fail to see how #is: is complex and messy. Really.

well for one thing all #is:-type of attributes have to be centralized in
one place, the #is: method.

a Morph that isMorph, isBeautiful and isWhatMyUncleLikes has to provide
the three answers to very different questions in the same place. Now if
another package needs to know if a Morph isMyCupOfTea, it must override
aMorph>>#is:

so #is: can not actually safely belong to a single package. while
#isWhatMyUncleLikes will only be in my package MyUncle, except if
someone else has the same kind of weird ideas about protocol names.

plus, looking for the senders of #isBeautiful immediately gives me all
classes responding to the protocol. with the #is: idea, all protocols
are mangled in one: you have to look at all #is: implementations, in all
objects (!) to see where you protocol went. if that's not messy, call me
Joséphine.

regards,

Stef



Reply | Threaded
Open this post in threaded view
|

Re: Object>>#is:? (was: Re: PackageDependencyTest)

Igor Stasenko
In reply to this post by Stéphane Rollandin
2010/3/4 Stéphane Rollandin <[hidden email]>:

>> A subclass inherits all aspects of parent class.
>> Think how many things you will need to override, if you would want to
>> subclass from a Number but don't behave like number.
>
> If #is: implementation has to reflect a class hierarchy, then I don't see
> how it can be any better than #isKindOf: and #isMemberOf:
>
>> Obviously, in your example you showing how to not abuse inheritance.
>
> My example is based on real, actual code. I use quite a feww isXXX methods
> to ask objects about a property or a protocol they may or not have. It works
> fine and allows me to control fine discriminations along the inheritance.

Then, please , give me a concrete example, where you will have 3 classes,
answering to isXXX message differently:

base (false) -> parent(true) -> subclass(false).

> That's not abusing, that's designing.
>

No it is abuse. By taking your example as a guide, then what stops me
from creating Morph subclass, which
answers false to isMorph message.  Do you still see nothing wrong with it?

>> And its nothing to do with #is: method :)
>
> Yes, because #isXXX messages are quite special methods: they mostly return
> mere ^true or ^false. So we are talking in this specific case about
> replacing a simple modular, orthogonal set of clear implementations with
> something much more complex and messy.
>

hmm.. i don't see anything messy here. It removes a bloat of #isXXXX
methods in many places.
Usually, when you introducing a new aspect in your class, you just
override the #is: method with following:

is: aSymbol
  ^ aSymbol == #myAspect ifFalse: [ super is: aSymbol ].


While if you use isXXX method, obviously you will need to add it to
base class (most of the times - Object) and then override it in your
class.


>>
>>> I have to be aware of the behavior of each implementation of #is: in the
>>> upward inheritance chain if I want to produce the proper tests. Going
>>> down,
>>> those tests will become more and more complex and hard to grok. Plus,
>>> reimplementing any of the #is: can possibly break any of the #is: in
>>> subclasses. So all #is: implementations in a given hierarchy are actually
>>> dependent. It's pure spaghetti code, as far away from OOP as it gets.
>>>
>>> I guess I'm missing something. how is this supposed to work ?
>>>
>> I think you should read mail archives.
>
>> First it was discussed about year ago (if i remember correctly).
>
> I did read the #is: proposal, at the time. No message that I remember
> addressed the kind of problem I expose above and that I had already in mind
> (although I did not participate in the discussion).
>
see above. Give me the reason, why a Morph subclass may want answer
false to isMorph message.

> Now I would appreciate a simple answer about what's wrong in my example; if
> there is confusion at this level, the #is: idea is certainly not as
> straightforward as it may seem.
>
>> Then Juan added it into Cius, cleaning a lot of isXXX method.
>> I think, we can ask Juan, how he feels about it, because he's the only
>> one who employed this idea so far.
>
> So it may be only a nice idea untested in a real situation. I am very
> dubious about its actual value; for one thing, it certainly cannot replace
> the isXXX I use in my own code.
>
Certanly , you can. In same way, as you can replace 100 named instance
variables in your class
with variable class, having 100 elements.

> regards,
>
> Stef
>


--
Best regards,
Igor Stasenko AKA sig.

1234