[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