Adrian Lienhard wrote:
I don't think you need to understand its internal details to be able to build tools. You do not need to enhance kernel but use the interface that is there already. E.g., Trait>>#users will return you all classes and traits that use a trait. Its just that this kind of information is lacking in the UI.
That's certainly part of it but not exclusively. For anything that is truly useful you will need to understand a lot about the implementation. Consider a simple example, like removing a method. If you want to build a useful tool, you need to know whether the method you remove originates from the class or from a trait and if so, which one. As far as I know there is no method directly answering that information so you need to know the implementation of traits to write that method. Etc.
Often you need that to understand the implementation to know how and where a tool is allowed to temporarily violate (or extend) the constraints. The browser, for example, pre-parses class definitions and checks whether actually executing it could cause harm (like changing a class definition not currently visible to the user). If the browser wouldn't do that it would be a good amount less usable. But for that you need to know how class interact and what can go wrong if you execute the class definition without pre-parsing it.
So I think you really do need to understand the implementation to write a useful tool. It is possible to get to a certain point without that but usually these points are trivial and not very useful. Case in point: Traits>>users. It is no problem for me to to change the class browser to show that bit of information. I have done it. But that is not enough by far.
I've been poking around in the traits implementation myself (fairly well documented in [1], and [2]) and although I have a very good understanding about the metaclass relationships in Squeak < 3.9 I found the traits implementation basically impenetrable. If I look at who implements a method and get ten implementors thrown at me where there used to be one or two, it's just not helpful. I stopped digging into it for that reason - the traits class kernel has become completely inaccessible to me.
Just to make that clear. This contradicts to your mail [3]. Since [2] the traits structure of the kernel was simplified. You even looked at this and you said in [3] that it indeed helps you to understand how this all works. I do not want to start a new endless discussion.
I think you misunderstand that message. I didn't say (and I didn't mean to say) that suddenly traits became all clear and simple and obvious ;-) I said (and I meant to say) that I understand some aspects now better (like the dual hierarchical structure) which lead me to conclude that it also makes me understand a lot better what I dislike about traits.
But really, I haven't grok-ed the implementation by a long shot. To give you an example, here is a simple question: Where do I find the addSelector:* and removeSelector:* family of methods and why? I can give you the answer for 3.8 (without looking at the code): Those methods must in Behavior with a few overrides in ClassDescription (where they manipulate the organization). They can't be higher in the hierarchy since they affect behaviors and they can't be lower since they should be shared between classes and meta classes. So without looking at the code I can deduce where these methods must be found. In 3.9 I can't give you that answer - I have no idea why addSelector:withMethod:notifying: is in one set of traits and addSelector:withMethod: is in another set of them and what the organizing principle behind it is.
Anyway, you are right, we had that discussion already. All I'm saying is that if you read that message of mine as saying "oh, now I got it" then you read it wrong.
Cheers, - Andreas