My idea is that we need a simple but powerful overall principle of organization.
(According to this proposal) we should adopt a variant of the well-known "layered" or "onion-skin" architecture, along with a principle that ensures sustainability:
(1) Architectural law: Modules may only depend on (use code in) modules "further in"/closer to the core. (Outward dependencies are forbidden.<*> Dependencies should be made explicit.)
(2) Principle of sustainability: In a sustainable system, the more central a module is, the less volatile and more conservative it needs to be.
That's all, technically, and these are not fascist laws but mere natural necessities.
Comments:
Obviously, closer to the core are more essential things. Outermost would be "applications" that are entirely optional.
The further out, the more you can do what you want (because the less others depend on you), but also the more work for you to adapt to changes in the inner layers. (But these should also change less.)
As code moves inwards, it gains importance, grows in value for others, but also takes on responsibilities.
The closer to the core: - The more the quality, stability, etc. of Squeak depends on it (Squeak: the program, the community, all the uses of Squeak) - The more sensitive the contents - The slower should code change. Use maximum foresight. Not haque du jour. - The higher standards should be imposed on changes (bug fixes yes, good code a must, "good to have" additions & quick toss-ins nope, code that doesn't belong there--no way José) - The more a module needs to be the "joint responsibility" of Squeak
Outermost would be Applications, which: - literally noone else depends on - are free do whatever they wish, - but are the sole responsibility of their authors to maintain
There is no longer any sharp line for what goes "into" Squeak here. This is very different from today's either-or-image situation.
(*) This means no more "String asUrl", because this makes the core module with String depend on the much less vital module PWS or whatever, so you have to load PWS to use strings. _Maybe_ we need to allow outer layers to add code in inner-layer-classes, but this creates spurious sideways interactions between modules. Perhaps only applications should be allowed to do this.
Pieces like Celeste the mail reader app would most likely become multi-layered, with the UI outermost, and more generally useful code in separate, more inward layers--e.g. code for sending e-mail, which may be useful in many other contexts, notably for posting code to a list or so.
There should be code that can validate that a (new) piece of code doesn't violate these rules, to automate things.
There would need to be separate update streams for each module (and updating mechanisms would need to be provided by the system as well). You choose which ones you want.
Up to today if you want the essential bug fixes you will get SqC's latest experimental code tossed in for free. And if you opt not to be an alpha pilot then basically you won't benefit from the community any longer (in effect you do the f-word). This ain't a good situation.
Note that many of SqC's experiments would become "far-out" layers (how appropriate). Or rather, SqC would need to divide their stuff into layers of well-behavedness too, if they want to contribute to the official system, so to speak. Otherwise the stuff would remain as applications.
This will be extra work for them and I don't know if they will want to do that. It would make SqC have to play by the same rules as everyone else, essentially. This is the part that I have been uncertain about whether it will happen, but I think this is necessary. We are at the point where pioneer town X needs to start collecting taxes and erecting law and order in order to keep growing. Well you've all played SimCity so you know.
Henrik
Quoting you - ("Sorry, newcomer X, but your code's just too shaky, we'll have to pass on that for now")
Please start by reading the numerous writings on modularity in Smalltalk before posting things like this. Joseph
At 14:37 02.06.2001 , Henrik Gedenryd wrote:
My idea is that we need a simple but powerful overall principle of organization.
(According to this proposal) we should adopt a variant of the well-known "layered" or "onion-skin" architecture, along with a principle that ensures sustainability:
(1) Architectural law: Modules may only depend on (use code in) modules "further in"/closer to the core. (Outward dependencies are forbidden.<*> Dependencies should be made explicit.)
(2) Principle of sustainability: In a sustainable system, the more central a module is, the less volatile and more conservative it needs to be.
That's all, technically, and these are not fascist laws but mere natural necessities.
Comments:
Obviously, closer to the core are more essential things. Outermost would be "applications" that are entirely optional.
The further out, the more you can do what you want (because the less others depend on you), but also the more work for you to adapt to changes in the inner layers. (But these should also change less.)
As code moves inwards, it gains importance, grows in value for others, but also takes on responsibilities.
The closer to the core:
- The more the quality, stability, etc. of Squeak depends on it (Squeak: the
program, the community, all the uses of Squeak)
- The more sensitive the contents
- The slower should code change. Use maximum foresight. Not haque du jour.
- The higher standards should be imposed on changes (bug fixes yes, good
code a must, "good to have" additions & quick toss-ins nope, code that doesn't belong there--no way José)
- The more a module needs to be the "joint responsibility" of Squeak
Outermost would be Applications, which:
- literally noone else depends on
- are free do whatever they wish,
- but are the sole responsibility of their authors to maintain
There is no longer any sharp line for what goes "into" Squeak here. This is very different from today's either-or-image situation.
(*) This means no more "String asUrl", because this makes the core module with String depend on the much less vital module PWS or whatever, so you have to load PWS to use strings. _Maybe_ we need to allow outer layers to add code in inner-layer-classes, but this creates spurious sideways interactions between modules. Perhaps only applications should be allowed to do this.
Pieces like Celeste the mail reader app would most likely become multi-layered, with the UI outermost, and more generally useful code in separate, more inward layers--e.g. code for sending e-mail, which may be useful in many other contexts, notably for posting code to a list or so.
There should be code that can validate that a (new) piece of code doesn't violate these rules, to automate things.
There would need to be separate update streams for each module (and updating mechanisms would need to be provided by the system as well). You choose which ones you want.
Up to today if you want the essential bug fixes you will get SqC's latest experimental code tossed in for free. And if you opt not to be an alpha pilot then basically you won't benefit from the community any longer (in effect you do the f-word). This ain't a good situation.
Note that many of SqC's experiments would become "far-out" layers (how appropriate). Or rather, SqC would need to divide their stuff into layers of well-behavedness too, if they want to contribute to the official system, so to speak. Otherwise the stuff would remain as applications.
This will be extra work for them and I don't know if they will want to do that. It would make SqC have to play by the same rules as everyone else, essentially. This is the part that I have been uncertain about whether it will happen, but I think this is necessary. We are at the point where pioneer town X needs to start collecting taxes and erecting law and order in order to keep growing. Well you've all played SimCity so you know.
Henrik
Squeakfoundation mailing list Squeakfoundation@lists.squeakfoundation.org http://lists.squeakfoundation.org/listinfo/squeakfoundation
-- - Joseph Pelrine [ | ] Daedalos Consulting Email: jpelrine@acm.org Web: www.daedalos.com/~j_pelrine
Smalltalk - scene and not herd!
Joseph Pelrine wrote:
Quoting you - ("Sorry, newcomer X, but your code's just too shaky, we'll have to pass on that for now")
I believe you misunderstood the point of that quote. My point was that you don't want to say these things out loud, well at least I don't want to, because it is extremely rude and inconstructive. And also you risk making a bad public impression if it turns out that you were the one missing the point.
Since you are a self-declared newcomer to Squeak, I won't blame you for not knowing that we have a community situation and a culture of uncoordinated contributions that we need to get working, which does not meet the requirements for the usual solutions and "numerous writings". If you had been around, then you would have known that there are people who oppose even the first principle I listed because the opposite is "convenient".
And as Daniel pointed out, the usual namespaces, modularity, and even team stuff, wouldn't be sufficient for the Squeak community even if we get them. We need to have a social structure around them. If however you do know about something beyond what you've mentioned here and on your web pages, that does address our unique situation, then please let us know.
And now hopefully we can get back to the issue I was intending to discuss with my posting. I'll respond to that later.
all the best, Henrik
Henrik,
And now hopefully we can get back to the issue I was intending to discuss with my posting.
Since nobody has commented on your original issue, I'll give it a try. I need to say that as much as I agree with your general principles, as much I must disagree with your concrete interpretation. In particular the first principle saying
(1) Architectural law: Modules may only depend on (use code in) modules "further in"/closer to the core. (Outward dependencies are forbidden.<*>
is a very good general principle but your interpretation of it in
(*) This means no more "String asUrl", because this makes the core module with String depend on the much less vital module PWS or whatever, so you have to load PWS to use strings.
is just utterly wrong. You could equally well declare that there must be none of the "isXYZ" methods in Object. That effectively leads to the style of using "((x isKindOf: Foo) or:[x isKindOf: Bar])" and that's most certainly not the right way of dealing with the issue, is it?! So...
_Maybe_ we need to allow outer layers to add code in inner-layer-classes, but this creates spurious sideways interactions between modules.
... my feeling is that the above should not read _maybe_ but _absolutely_. Please note that there are no spurios interactions between modules as long as long as methods are added and not modified and that adding methods can be done in a perfectly safe way if selector name spaces are supported. In this case PWS would - by using #asUrl - make itself a dependent of the URL module (making #asUrl and the URL classes part of PWS itself defeats your own interpretation of a layered architecture) the URL module would (by implementing a method in String) be a dependent of the String (or Core) module and everything follows nicely your general principle.
Similar things can be said about some other concrete interpretations you are giving. Two examples are
There is no longer any sharp line for what goes "into" Squeak here. This is very different from today's either-or-image situation.
... and ...
There would need to be separate update streams for each module (and updating mechanisms would need to be provided by the system as well).
Neither do your general principles imply that there is no longer going to be a sharp line nor do they imply separate update streams. Whether or not there is a sharp lines depends on the distribution and inclusion mechanisms used (meaning that there could very well be an extremely sharp line for various things - just take the SWT image and check it out; a very sharp line can be seen here cutting off every last bit of media related stuff in favour of other things [this is no complaint, just an observation]) and the updates could still come out of one source - all that is required is a dispatch mechanism and whether this mechanism is on the client or the server side is a completely independent issue.
So, I do agree with you on the terms of the general principles. But I can hardly agree with your interpretaton in the concrete context.
Cheers, - Andreas
My central argument was that we need to have a process for accepting/filtering etc. modifications to the shared code base, which allows people to work freely where appropriate but also to make contributions (or more importantly, allow us to actually use others' contributions). Does any existing tool address this problem? And this is not just a problem of software engineering, but of social engineering.
I think the tension between Squeak and existing team-process tools could be described as, dare I say it this week, one between unmanaged evolution and managed, explicit design.
Thus I don't think any existing concepts, team tools, etc. will completely help us with this problem. And having "owners" for classes, like in Envy or so, I think that is completely unrealistic here.
I would not be the first to claim that team-oriented solutions require more formalized group structures and organized development than an Internet open source community. I don't really see that we could have any formal roles at all. It won't work in practice. The few we have, for vm platform keepers, only work so-so (witness the CVS debates). And this is not a criticism of the keepers but a note that such fixed, high-dependability roles are problematic.
Henrik
Henrik,
I agree with much of what you've said here, but have a bit of a problems with:
(*) This means no more "String asUrl", because this makes the core module with String depend on the much less vital module PWS or whatever, so you have to load PWS to use strings. _Maybe_ we need to allow outer layers to add code in inner-layer-classes
One of the big advantages that a dynamically typed language gives us is the ability to add class extensions without pain. For the module system to ignore this would be a real shame. Let's not impose on ourselves, through our tools or through our best practices patterns, the same constraint that the Java folks have.
but this creates spurious sideways interactions between modules. Perhaps only applications should be allowed to do this.
I've heard this before, by intelligent people, but I haven't seen convincing evidence. I've made several base class extensions over the last 8 years, and have never been bitten. Can you give an example of the problem?
Thanks, Bob
Bob Hartwig wrote:
but this creates spurious sideways interactions between modules. Perhaps only applications should be allowed to do this.
I've heard this before, by intelligent people, but I haven't seen convincing evidence. I've made several base class extensions over the last 8 years, and have never been bitten. Can you give an example of the problem?
Thanks, Bob
Well, this is essentially the problem addressed by allowing separate modules use the same selector for different methods. If you have that ability then there's no problem I guess.
We'll probably need to allow it, but I don't realistically believe this dual-methods thing will be among the first things we choose to spend time on. It's really a quite rare special case. I think we might classify it as allowed but preferrably avoided practice (cf. adding methods to Object). The "further in" toward the core, the more we'd try to avoid it unless warranted.
But I though about this example, in code inside a module:
'bla bla' selectorDefinedTwice
Here, the Compiler creates a String. Are present implementations that allow this smart enough to instantiate a String as it is known in the creating namespace, with the right method defined? Because the Compiler's namespace, when the literal-compiling method is defined, would certainly not know of either of the two definitions.
The general point is that this string literal is just an implicit reference to the String class and might not be caught by the several-definitions functionality, as an explicit reference, say,
String newWith: 'bla bla'
would.
But this is a tiny pixel in the big picture.
Henrik
Henrik Gedenryd wrote:
Well, this is essentially the problem addressed by allowing separate modules use the same selector for different methods. If you have that ability then there's no problem I guess.
We'll probably need to allow it, but I don't realistically believe this dual-methods thing will be among the first things we choose to spend time on. It's really a quite rare special case. I think we might classify it as allowed but preferrably avoided practice (cf. adding methods to Object). The "further in" toward the core, the more we'd try to avoid it unless warranted.
But I though about this example, in code inside a module:
'bla bla' selectorDefinedTwice
Here, the Compiler creates a String. Are present implementations that allow this smart enough to instantiate a String as it is known in the creating namespace, with the right method defined?
I haven't followed the namespace issues too closely, so I have a question here: Do you mean that in each namespace there is a different String class object, with a different method dictionary? In that case, how would a String created in one namespace work within another? It seems like it would be complicated to allow methods in one module perform lookups in a different namespace than those in another module, while retaining interoperability of the data.
In many ways, I think it would be simpler to ensure that the symbol #selectorDefinedTwice defined in module Foo is a different object from the symbol #selectorDefinedTwice defined in module Bar. (That is, they have the same string representation, but different identities.) That would mean that classes could use flat method dictionaries, shared between all namespaces. It would be implemented by having a separate symbol table for each namespace, arranged heirarchically.
When compiled, your method (in Foo) calling
'bla bla' selectorDefinedTwice
would contain a reference to the symbol #selectorDefinedTwice found in Foo's symbol table, rather than Bar's symbol table. Any way your method was called (including callback initiated from another module's code), it would automatically call the right selectorDefinedTwice method, without any change to the method lookup semantics.
Or is this crazy, for some reason I don't yet appreciate?
-Jesse
I think this is an idea worth experimentation. My first impression is that it would create more problems than it solves. If you pass any symbols from the code in one module to the code in another module, then use them as keys in identity dictionaries, you're going to get some un-expected results. And, for the novice, they'll be very difficult to comprehend (and thus debug). You also will not avoid having to re-do the development tools (imagine seeing two methods of the same name in the browser...which module does it belong to? how do I compile a new method for a specific module?).
I think the changes to implement this scheme would be no less difficult than the changes to implement it via enhancing the message look up and the method dictionaries. It may work, but it's a little more obscure IMO. If you've ever looked at the method lookup code, it's very straightforward.
The tricky thing is not really the mechanism itself, but making it simple to comprehend. The simple examples that have been discussed so far are...simple. What happens in the case that your module imports another module that overrides a method? Does your module use the overridden method, or the original one? What if you import two modules that override the same method? Which one do you use? Do you allow a way to explicitly prefer one over the other? Do you go by the order the modules were imported? What kind of complexity will this add to the method dictionary (now not really a dictionary but a more complex animal). You're really adding a new dimension to the method lookup scheme.
We could probably come up with a simple rule (such as breadth first, import order), and allow some mechanism to override the default lookup sequence (kind of like "super" allows us to override the default lookup scheme)...but again, whatever it is, it needs to be simple for 99% of the cases.
How would a symbol based approach solve this problem? Would it choose the symbol defined by one of it's imported modules?
It's difficult...it's been discussed for years...but it would be a big step on the trail to modularity and it would help put Squeak way ahead of other languages in this regard.
- Stephen
I haven't followed the namespace issues too closely, so I have a question here: Do you mean that in each namespace there is a different String class object, with a different method dictionary? In that case, how would a String created in one namespace work within another? It seems like it would be complicated to allow methods in one module perform lookups in a different namespace than those in another module, while retaining interoperability of the data.
In many ways, I think it would be simpler to ensure that the symbol #selectorDefinedTwice defined in module Foo is a different object from the symbol #selectorDefinedTwice defined in module Bar. (That is, they have the same string representation, but different identities.) That would mean that classes could use flat method dictionaries, shared between all namespaces. It would be implemented by having a separate symbol table for each namespace, arranged heirarchically.
When compiled, your method (in Foo) calling
'bla bla' selectorDefinedTwice
would contain a reference to the symbol #selectorDefinedTwice found in Foo's symbol table, rather than Bar's symbol table. Any way your method was called (including callback initiated from another module's code), it would automatically call the right selectorDefinedTwice method, without any change to the method lookup semantics.
Or is this crazy, for some reason I don't yet appreciate?
-Jesse
Squeakfoundation mailing list Squeakfoundation@lists.squeakfoundation.org http://lists.squeakfoundation.org/listinfo/squeakfoundation
Stephen Pair wrote:
I think this is an idea worth experimentation. My first impression is that it would create more problems than it solves. If you pass any symbols from the code in one module to the code in another module, then use them as keys in identity dictionaries, you're going to get some un-expected results.
I'm not sure how often the results would really be un-expected. Where two modules want to use the same symbol in a given identity dictionary, they will generally be related by module dependency, so both will generally refer to the same symbol through the heirarchical nature of symbol tables.
Alternatively, one could distinguish between symbol literals and selector invocations, looking up all symbol literals in a global context. (This does, admitedly, require one to specify a selector namespace for #perform: functionality. That might prove to be necessary, or at least desireable, with multiple method dictionaries, too, though.)
And, for the novice, they'll be very difficult to comprehend (and thus debug).
Yes, this is a likely problem. I think multiple lookup dicitonaries could produce confusing results along the same lines: "Why am I getting a doesNotUnderstand, when I've defined this method? Why is this method being called instead of the version from my module?"
You also will not avoid having to re-do the development tools (imagine seeing two methods of the same name in the browser...which module does it belong to? how do I compile a new method for a specific module?).
It certainly doesn't eliminate the need for reworking the tools. Either way you cut it, the tools will have to allow the programmer to specify which namespace you're working in, and for showing only the methods relevant to that namespace. For the most part, I think the tools' interface could be much the same in both cases.
I think the changes to implement this scheme would be no less difficult than the changes to implement it via enhancing the message look up and the method dictionaries. It may work, but it's a little more obscure IMO. If you've ever looked at the method lookup code, it's very straightforward.
I've not looked at it much. Naively, I would guess the tools support would likely take about the same amount of work, but the symbol-based approach requires no work at the VM level. Wouldn't making the method lookup logic more complex add runtime overhead, too? But perhaps I'm completely wrong here.
The tricky thing is not really the mechanism itself, but making it simple to comprehend. The simple examples that have been discussed so far are...simple. What happens in the case that your module imports another module that overrides a method? Does your module use the overridden method, or the original one? What if you import two modules that override the same method? Which one do you use? Do you allow a way to explicitly prefer one over the other? Do you go by the order the modules were imported?
Hmm? These exact issues exist with any implementation of method namespaces.
What kind of complexity will this add to the method dictionary (now not really a dictionary but a more complex animal). You're really adding a new dimension to the method lookup scheme.
No, I don't think this changes the nature of method dictionaries at all, even conceptually. It does change the nature of Symbols, though. Symbols become attached to particular namespaces, so instead of simply #someSelector, you conceptually have #someSelector-from-Foo. (In fact, Symbols could be extended with a namespace instance variable that could be used by various tools.)
We could probably come up with a simple rule (such as breadth first, import order), and allow some mechanism to override the default lookup sequence (kind of like "super" allows us to override the default lookup scheme)...but again, whatever it is, it needs to be simple for 99% of the cases.
How would a symbol based approach solve this problem? Would it choose the symbol defined by one of it's imported modules?
I don't think it does solve the problem; but I don't see how multiple method dictionaries does, either. This is more a matter of the tools. Generally, yes, the compiler would insert a symbol from one of the imported modules, if it exists, or else would have a new one created in the current module's table. A symbol-based implementation could be quite flexible in handling special cases, for instance by asking the programmer which imported module's symbol to use in the case of overlap.
Hmm, here's a possible problem case.
Core module:
SomeClass>>meth1 "do some stuff" self meth2. "do some more stuff"
SomeClass>>meth2 "do some different stuff"
Extending module:
SomeClass>>meth2 "some extended version of meth2"
Now, SomeClass>>meth1, when called from the extending module, won't call the extended version of meth2, because it references the core version. While symbol-based modularity could in principle handle calling the core meth2 from the extended meth2, I don't see how it would possibly allow the core meth1 to call the extended meth2.
This situation could either be extremely rare (and bad practice), or it could be fairly common; I don't know. But if you can cite a place where this structure is useful, and describe how a method dictionary-based implementation of modularity could solve it, I'll be sold. Probably. ;)
-Jesse
We'll probably need to allow it, but I don't realistically believe this dual-methods thing will be among the first things we choose to spend time on. It's really a quite rare special case. I think we might classify it as allowed but preferrably avoided practice (cf. adding methods to Object). The "further in" toward the core, the more we'd try to avoid it unless warranted.
Hmmm...I don't think this is a special case at all...you may be right about it not being one of the first things implemented, but adding methods to Object is done quite commonly (and by necessity). Usually, adding a method to Object is cleaner than trying to avoid doing so (see Andreas' argument in favor of #is* methods over using #isKindOf:). The real problem with doing such is the fact that we don't have a solution for method namespaces. Avoiding such method additions leads to code that is convoluted, difficult to maintain, and generally not well written.
Here, the Compiler creates a String. Are present implementations that allow this smart enough to instantiate a String as it is known in the creating namespace, with the right method defined? Because the Compiler's namespace, when the literal-compiling method is defined, would certainly not know of either of the two definitions.
Your concept of method namespaces is a bit off here. The compiler does not instantiate anything...it only resolves names. When a String is instantiated (in the case where there are two different implementations of #selectorDefinedTwice), the same String class is used (unless you've defined your own String class in your module), however the mechanism in which the *selector* is resolved to a method is smart enough to choose the correct method based on the context (module) in which the message was sent.
This is why I said that this would require deep modifications to the message dispatch mechanism and to method dictionaries. However, it's not impossible, it probably needs to be prototyped in the image before expending the effort to change the VM (which will ultimately be needed if a solution that performs well is desired). Also, such a change in the dispatch mechanism of the VM may adversely affect the performance of Squeak overall, but hopefully the impact can be made small enough that the trade off is well worth it.
Also, there is a real life analogy that can be made. When you are sent messages from people in real life, you are likely to respond in different ways depending on who is sending the message...you may even respond more or less promptly depending on the sender (my wife gets a very high priority response...most times ;)).
Finally, having such a mechanism in place may ultimately allow us to reconcile the benefits of a Morphic all in one design vs. an MVC keep everything separate. With such a mechanism, a GUI module that depends on a Morphic module could add Morphic methods to a BankAccount without affecting (or intermixing) with the domain Behavior that the BankAccount domain module creates. (We may need to expand the scope to allow modules to add instance variables in addition to methods however). But, let's take it one step at a time...there are likely to be a lot of people that label me a heretic based on this final comment (due to the almost religious status that MVC has achieved)...but I'd love to have a system where this sort of thing could be experimented with.
- Stephen
P.S. Dave Simmons was mentioned as an authority on this subject...does he have any papers on web about this topic?
Stephen Pair wrote:
[...] When a String is instantiated (in the case where there are two different implementations of #selectorDefinedTwice), the same String class is used (unless you've defined your own String class in your module), however the mechanism in which the *selector* is resolved to a method is smart enough to choose the correct method based on the context (module) in which the message was sent.
This is why I said that this would require deep modifications to the message dispatch mechanism and to method dictionaries. [...]
Stephen, I'd be interested in hearing your opinion of the suggestion I just made, of using the same method dictionaries, but different symbol tables in different namespaces. That would require no changes to the method dispatch mechanism or to method dictionaries. I'm not sure whether it would require more or less work to implement the tool support, though.
-Jesse
Stephen Pair wrote:
We'll probably need to allow it, but I don't realistically believe this dual-methods thing will be among the first things we choose to spend time on. It's really a quite rare special case. I think we might classify it as allowed but preferrably avoided practice (cf. adding methods to Object). The "further in" toward the core, the more we'd try to avoid it unless warranted.
Hmmm...I don't think this is a special case at all...you may be right about it not being one of the first things implemented, but adding methods to Object is done quite commonly (and by necessity).
OK, the special case I meant was when two different namespaces define different methods for the same selector in the same class. That has to be at least a little bit rare...
Your concept of method namespaces is a bit off here. The compiler does not instantiate anything...it only resolves names.
Correct me if I'm wrong, but I insist (with moderate certainty) that when the source code contains a string literal (like 'bla bla') the compiler creates a string literal that is stored within the CompiledMethod. And this is done by code in the compiler.
Also, there is a real life analogy that can be made. When you are sent messages from people in real life, you are likely to respond in different ways depending on who is sending the message...you may even respond more or less promptly depending on the sender (my wife gets a very high priority response...most times ;)).
... BankAccount ...
Yah, now you are really talking about perspectives and that is kind of my playground. If you have perspectives (which in this context in effect yield multiple method dictionaries for the same class/instance) then you won't need to hack this into the name spaces. You can do it cleanly. In fact you can even disclose different slots (inst vars) in an object to different perspectives, and it's fully natural to do so. Not a hack or a heresy at all.
In fact, single inheritance is really weak in a truly modular context. I think many of the complications needed to support modularity go away with a more powerful reflective paradigm/single-inheritance substitute. (I guess this was a plug for my perspectives system, but I'm not sure. I see this as a very long-term campaign anyway.)
Henrik
squeakfoundation@lists.squeakfoundation.org