SystemNavigation and deprecated methods

Roel Wuyts wuyts at iam.unibe.ch
Fri Aug 15 18:04:47 UTC 2003


Some comments dispersed in the text. But a good conclusion at the 
bottom :-)

On Friday, Aug 15, 2003, at 18:19 Europe/Zurich, Andreas Raab wrote:

> Hi Roel,
>
>> Because you then have base-level code that directly accesses
>> meta-level methods. If ever you want to remove reflection from
>> your image you risk running into big problems, because it is
>> very hard to determine all the places in the code where the
>> reflection is actually used.
>
> I don't quite understand what you mean here. Assuming that I use 
> reflection
> code at all, isn't it _always_ the case that I will have to check the 
> places
> in which that code is actually used? How would (for example) checking 
> for
> the senders of Behavior>>allCallsOn: be different from checking for the
> senders of SystemNavigation>>allCallsOn:in:?
>
> So the only situation in which having the functionality in 
> SystemNavigation
> would be advantageous is when you don't use reflection at all and can 
> just
> remove that class. But it seems quite natural to me that assuming we 
> use
> extension methods we remove those methods along with the class. Again, 
> I see
> no recognizable difference here.

I wasn't talking about means here. What you can accomplish with mirrors 
(or classes) you can also accomplish sometimes with extension methods. 
My point was exactly that: you risk running into problems, unless you 
have taken care to properly identify them. Note that removing class 
extensions will not solve the problems of knowing where you use 
metalevel methods, just that you can easily remove them.

>
>> Sure. Every problem in computer science can be solved by
>> introducing an extra level of indirection :-)
>> No, serious, you run into problems because if you introduce a simple
>> proxy (let's call it 'aProxy', instance of class MyProxy) for
>> an object a (instance of A), then what happens if you evaluate
>> 'aProxy class selectors'? That is the point I wanted to make. No
>> object-orientedness will save you there, I'm afraid :-(
>
> Oh, but absolutely. The only reason why the above wouldn't work in 
> Squeak is
> that #class is not a message send. The point has been made various 
> times by
> various people that this is a significant problem for proxies. And for 
> the
> most part I agree. So if we were to remove that restriction then you 
> could
> trivially answer a ClassProxy if you wanted to. Let's not confuse 
> certain
> shortcomings of Squeak (which could be trivially fixed) with the larger
> scope.
>
>> Yes, that's why I like to have responses like yours; no
>> question about it. Note that we are having two discussions at
>> the same time in this thread, I think. One is the general
>> overall discussion (all the stuff above and the stratification
>> below, etc.). The other one is the concrete problems that started
>> the whole thread in the first place. For the latter, I thought
>> that you only objected to some of the methods being gone from
>> class. Is that right? If so, could you give a concrete list?
>
> That's correct. For the list, let's see:
> #allCallsOn:
> #allUnsentMessages
> #browseAllAccessTo:
> #browseAllCallsOn:
> #browseAllStoresInto:
> #allUnreferencedClassVariables
>
> Those are the ones that I would want to ask a class directly (mostly 
> because
> they're not immediately accessible from the tools for various of the 
> queries
> that come up often).
>
>> The clear division between base level code and meta level code, as I
>> tried to made clear in the paragraphs at the beginning of
>> this mail. By itself stratification is not that new; for
>> example, I need it in Soul, since I have to marry two
>> different languages. You clearly see the difference between
>> the logic (meta) code and the Smalltalk (base) code.
>
> I see what you're saying. In some respects I agree (though maybe not 
> for the
> same reasons ;) that having some sort of fence between the base and 
> the meta
> level representations can be advantageous. But I think that (for me) 
> this
> fence shouldn't really appear as a stratification which sounds like 
> lots of
> extra indirections but rather by some sort of "context switch" (think:
> perspectives) where you have to be explicit about when you are meta 
> and when
> you aren't but can use the same convient way of thinking about and 
> referring
> to objects and their methods once you really are meta.
>
> Let me try to illustrate this in a practical example: I think we both 
> agree
> that when I write a class-side (utilitiy) method I should not be able 
> to
> access the meta level directly, if only for preventing mistakes, e.g.,
> writing something like "name := something" (this actually happened to 
> me).
> But I don't think that this problem should be addressed by requiring an
> extra indirection if I _do_ want in fact to be meta such as in 
> "(ClassMirror
> on: self) setNameTo: #Mumble" but rather something where I perhaps 
> have an
> explicit annotation for this method that means, yes, I am now in the 
> meta
> level of the system and I (hopefully ;) know what I'm doing.

Agreed. Like I said above, I can imagine different ways of 
accomplishing this. For me this discussion is not about that. Very 
stupidly, prefix every meta-level ethod with name (or add method 
namespaces) and you can do 'senders of' and get all the exact places. 
Or ... or ...

>
>> So there you have to make a clear separation or suffer the
>> consequences. When the meta language and the base language are the
>> same, and the representation of the language are objects just as base
>> level objects (the Array object, for example), it is very
>> easy to write statements that jump between base and meta level
>> code all the time ('myObject class selectors', for example).
>> By itself this is not a problem, until you suddenly need to
>> change some part of the representation (because your things
>> do not live in your image anymore).
>> Then all thse seemingly ok and very clear statements become quite
>> difficult. Again, this is not to say that I want such a
>> complete system in Squeak: that would be a research goal
>> (and you'll end up with Strongtalk or something very similar).
>> But that is part of the motivation why we make the separation,
>> implementing it on a separate class. Then we can still add
>> class extensions to point to these things,
>> or make a global variable to hold the instance, etc.
>
> Okay, now I understand where you are coming from. Thanks for the
> explanation. Though I have to say that it feels to me like the wrong
> solution to the right problem ;-) This sounds a lot like a problem 
> which
> might be much better addressed by using something like Traits in 
> combination
> with selector namespaces.

Yes, I was typing the same in the above explanation :-) So I guess we 
are in sync now :-) :-) I am happy that I was able to explain you the 
things without resorting to too much black magic and papers :-)

>
> Cheers,
>   - Andreas
>
>
>
Roel Wuyts                                                   Software 
Composition Group
roel.wuyts at iam.unibe.ch                       University of Bern, 
Switzerland
http://www.iam.unibe.ch/~wuyts/
Board Member of the European Smalltalk User Group: www.esug.org



More information about the Squeak-dev mailing list