[FIX][KCP] KCP-0112-FixCanUnderstand [long!]
Julian Fitzell
julian at beta4.com
Tue Dec 16 01:21:06 UTC 2003
Colin Putney wrote:
>
> On Dec 15, 2003, at 2:58 PM, Julian Fitzell wrote:
>
>> If you ask me, this is the crux of the argument that the rest of the
>> thread is missing. self subclassResponsibility is not really a meta
>> marker on the class - it's an error. It's implemented as:
>
>
> I'd go even futher here:
>
> First, the fact is Smalltalk doesn't really have the notion of abstract
> methods. I don't see this as a short coming of Smalltalk. Abstract
Nor do I
> methods are only needed in languages that confuse classes with type, as
> Peter mentioned earlier. In order to support polymorphism you need to
> put the method "too high" in the class hierarchy so that the type
> checker won't complain when it gets sent to the supertype.
>
> Now, a problem that Smalltalk *does* face is that MNU errors are
> ambiguous. When you get one, the problem might be in either then sender
> or the receiver. That is, either the message shouldn't have been sent,
> or the receiver should have understood it. When a programmer calls
> #subclassResponsibility or #shouldNotImplement, what she's really doing
> is disambiguating the error.
This is an interesting way of looking at it and a subtlety I hadn't
quite put my finger on.
> In the case of #subclassResponsibility, she is saying that the message
> was correct, and the object should respond to it. The fact that it
> didn't is an error, and the fix is not to avoid sending the message, but
> to implement the method. The reverse situation applies to
> #shouldNotImplement. The programmer is telling us that the message makes
> no sense to this object and should not have been sent. This
> clarification is especially handy when the limitations of single
> inheritence (ie, lack of Traits) cause the object inherit an
> inappropriate method, which, if activated, would result in an error even
> more obscure than MNU.
>
> I think #shouldNotImplment is misnamed. It should really be
> #cannotUnderstand. Conversely, #canUnderstand: is asking whether or not
> it makes sense to send a certain message to an object. So, for the
> following code, I think it would be reasonable to get a
> #subclassResponsibility error, but not a #shouldNotImplement error.
> (object canUnderstand: #foo)
> ifTrue: [object foo[]
I agree that #shouldNotImplement is a strange name (I think
#shouldNotBeCalled or something would be better since it *has*
implemented the method). But, I'm still not sure #canUnderstand: should
be looking at the method source to come up with an answer. I understand
the desire for a mechanism that works like that, but using method calls
as a marker to anything but the human eye seems pretty fishy to me.
The "right" solution, I suppose, is to get rid of the uses of
#shouldNotImplement by using Traits (or whatever), since their very
presence smells of a hack in the first place. Adding any behaviour to
#canUnderstand: to account for this hack is then, by definition I think,
also a hack. Which I guess is possibly ok as long as we accept it and
comment it as such. But I think it's better to limit the hack to
getting an error when you do something wrong (calling a method that
should not ideally even be implemented) rather than pushing it into
other methods: the hack will still be a hack but it will be harder to
isolate.
For example, someone might write:
true ifTrue: [self shouldNotImplement]
or:
false ifTrue: [self shouldNotImplement]
and we couldn't write code that would actually catch both cases
properly. Hack, hack, hackety, hack... :)
Julian
More information about the Squeak-dev
mailing list
|