Andreas, I prefer refactoring, but refactoring assumes a closed world
approach where you control all the pieces of the puzzle. It simply is not always possible to refactor (because you do not have the source, because you do not want to create a fork, because you have other programs that absolutely rely on the old behaviour, etc.). In that case extending the existing software from within your own package helps, but should be used sparingly for all the reasons you mention. Note that a decent module system should support both. On 11 Mar 2007, at 11 March/18:56, Andreas Raab wrote: > Lex Spoon wrote: >> Yes, that is fair generalization. I would like the default module >> format to allow unanticipated reuse. Just look at the packages >> Squeakers post for each other, and you will see all kinds of things >> that modify the system. How could you write something like Shout >> if a >> module cannot change the system text editor? > > Err, by refactoring it in a way so that you can? We have already > various abstractions (AppRegistry) and there is nothing wrong to > have one that allows for syntax highlighting - with a common > protocol that allows other clients to hook into it, instead of > hacking the system text editor directly. Coincidentally, this is > *precisely* what I referred to earlier wrt. explicit vs. implicit > interactions. As it stands, loading an alternative syntax > highlighter will (almost necessarily) clash with shout; with that > interface both modules could use the same ground rules, could be > loaded side by side and could be activated depending on the context > you need them in. > > Cheers, > - Andreas > |
Roel Wuyts wrote:
> Andreas, I prefer refactoring, but refactoring assumes a closed world > approach where you control all the pieces of the puzzle. I would call access to all pieces of the puzzle "open" not "closed" but be that as it may... > It simply is not always possible to refactor (because you do not have > the source, because you do not want to create a fork, because you have > other programs that absolutely rely on the old behaviour, etc.). In that > case extending the existing software from within your own package helps, > but should be used sparingly for all the reasons you mention. > > Note that a decent module system should support both. Which I have advocated earlier myself. I have never doubted that there are situation in which patching another module is advantageous and desirable. Which is why I don't understand why some people are so opposed to the idea of having the other end of the spectrum (isolation) available as well. Cheers, - Andreas |
Indeed. I think we need both. In the same model.
On 12 Mar 2007, at 12 March/08:32, Andreas Raab wrote: > Roel Wuyts wrote: >> Andreas, I prefer refactoring, but refactoring assumes a closed >> world approach where you control all the pieces of the puzzle. > > I would call access to all pieces of the puzzle "open" not "closed" > but be that as it may... > >> It simply is not always possible to refactor (because you do not >> have the source, because you do not want to create a fork, because >> you have other programs that absolutely rely on the old behaviour, >> etc.). In that case extending the existing software from within >> your own package helps, but should be used sparingly for all the >> reasons you mention. >> Note that a decent module system should support both. > > Which I have advocated earlier myself. I have never doubted that > there are situation in which patching another module is > advantageous and desirable. Which is why I don't understand why > some people are so opposed to the idea of having the other end of > the spectrum (isolation) available as well. > > Cheers, > - Andreas > |
In reply to this post by Roel Wuyts
Roel Wuyts <[hidden email]> writes:
> Andreas, I prefer refactoring, but refactoring assumes a closed world > approach where you control all the pieces of the puzzle. > > It simply is not always possible to refactor (because you do not have > the source, because you do not want to create a fork, because you > have other programs that absolutely rely on the old behaviour, etc.). Exactly. It also assumes that even if you have the code, you can convince the other guy to make the change. This is a significant burden. You are better off if you can propose your module and then let people try it. If it is popular, then the other guy will know your code is not loopy and so will be more amenable to cooperating on a refactoring. Shout replaces the system text editor, which in my mind is an invasive change that is just the sort of thing hard-shelled modules would be likely to disallow. I can assure you, the behavior of a lot of things changes when you have Shout loaded. There are plenty of other examples, though. Extreme examples would be Zurgle and Genie. These old packages changed various classes in Morphic when they were loaded. Interestingly, one became standard, and the other faded and stopped being maintained. Open modules worked well for these cases; they let the proponents post their code for people to play with, without immediately needing to get the standard Morphic classes refactored to suit them. And anyway, they were both probably lobbying for standard inclusion, anyway, so refactoring hooks for them would be superfluous overengineering. Those are extreme examples. There are a lot of intermediate examples, too, where you want to add a few thing to Object to make everything go smoothly. Look at the code for GOODS or SIXX sometime. GOODS adds "isGoodsImmutable", which I guess you would say should be supported through a type-check mechanism. Fair enough. How about SIXX's addition of Object>>sixxInitialize ? This method is supposed to be called when an object has finished initializing. It cries out to be placed in class Object, so that you can just send this message to the object and let it take care of it. In this case, I don't even think the system code should be refactored -- this is a great Smalltalk design the way it is. In practice, it has proven very valuable that Smalltalk modules are allowed to modify the system classes. This is a dangerous thing to do, of course, but I would really hate to handicap the above fine packages just because of the *potential* for danger. Instead, we should admit that inter-module conflicts exist, and deal with them head-on, as they happen.... > In that case extending the existing software from within your own > package helps, but should be used sparingly for all the reasons you > mention. > > Note that a decent module system should support both. Fully agreed on both. Lex |
On 12 Mar 2007 23:53:15 +0100, Lex Spoon <[hidden email]> wrote: Also, it's a requirement in my remote code system that loading one module using whatever mechanism physically CANNOT start causing strange symptoms in other modules. . This is a basic security requirement. What I'll probably do is prevent modifications to core classes like Object and String.
You can never be sure that whatever object you're working with does in fact have Object as a superclass. This is particularly relevant with my project (DPON): I'm capturing message sends to objects to implement remote objects. In my opinion, code not related to the functionality of a particular object (such as any of the morphic methods on Object) should not be there. It should be refactored so that it is in the classes relevant to what the code is trying to do. For example, Object>>asXML should really be something like XMLEncoder>>encodeObject:, where the implementation makes use of >>isKindOf: or >>canUnderstand:. It's a bit more verbose, but prevents inter-module conflicts and keeps your code where it is relevant. Michael. |
In reply to this post by Andreas.Raab
**thanks**
I like this kind of discussions. (I hope to get someone working on solution 3 but money is scarce :) Now about modules, I found several occasions (and this is also the idea behing open implementation of kiczales before they went in aop) is that the boundary of modules are often at the wrong level of abstraction since sometimes you want to be able to change deep implementation points. So in some cases (network for example) people do not want to use library since they lose their ability to control low level. Some people pointed to me ml functors with the experience that it was powerful but that often people were using functors on functors on functors leading to system that noone can understand. Stef On 10 mars 07, at 22:16, Andreas Raab wrote: > stephane ducasse wrote: >> Did you encounter cases where you would have like to have >> different versions of the same component/modules running in the >> same image. > > Sure. Consider Croquet: It relies on replicated computation which > means that the replicated islands must have identical code based to > have the same behavior. But what happens when you link to a space > which uses a different (older or newer) version of a module that is > already loaded in the space you are in? As far I can see there are > only three options:] > > 1. Don't ever allow it. That's our current solution, i.e. all > spaces linked together must use the same code base. For the obvious > reasons this is neither particularly scalable nor desirable. > > 2. Force migration of "older" spaces. This may be an acceptable > solution if the number of spaces linked together is relatively > small. However it has the disadvantage that you create "waves" of > updates since participants are linked together in unforeseen ways > (compare this to a WWW where each web page can only be linked to > another webpage of the same version and where upgrading one would > implicitly require upgrade all the ones it links to - I think you > can see the basic problem with the approach). > > 3. Have these modules sit side-by-side. In reality, this is the > only scalable, secure and desirable solution. > > Cheers, > - Andreas > > |
In reply to this post by Lex Spoon-3
Lex Spoon wrote:
> Shout replaces the system text editor, which in my mind is an invasive > change that is just the sort of thing hard-shelled modules would be > likely to disallow. Not at all. Shout uses an API (AppRegistry) that is specifically provided for clients so they can pick up an alternative text editor if they choose to. No module system in the world would disallow interaction that is based on an explicitly provided API. Besides why do you call the change "invasive"? It does not touch any code in the system text editor, all it does is using an API that was explicitly provided for that purpose. Why is that "invasive"? > I can assure you, the behavior of a lot of things > changes when you have Shout loaded. True. But since Shout uses an API a client can decide whether it wants to use any generic morphic text editor or whether it wants to use a specific one. That is different to your "solve conflicts with overides" approach which would give the client *no chance* to decide what to do. With Shout as it is (using the AppRegistry) I can easily switch the user's default choice of text editor to something else if that were necessary for my app to work properly. With a version that would hack text editor directly I would have *no such choice* making it somewhere between hard and impossible to actually get things working. > There are plenty of other examples, though. Extreme examples would be > Zurgle and Genie. These old packages changed various classes in > Morphic when they were loaded. Interestingly, one became standard, > and the other faded and stopped being maintained. Open modules worked > well for these cases; they let the proponents post their code for > people to play with, without immediately needing to get the standard > Morphic classes refactored to suit them. And anyway, they were both > probably lobbying for standard inclusion, anyway, so refactoring > hooks for them would be superfluous overengineering. Oh, that's cheap. It's not even worth responding. > Those are extreme examples. There are a lot of intermediate examples, > too, where you want to add a few thing to Object to make everything go > smoothly. Look at the code for GOODS or SIXX sometime. GOODS adds > "isGoodsImmutable", which I guess you would say should be supported > through a type-check mechanism. Fair enough. How about SIXX's addition > of Object>>sixxInitialize ? This method is supposed to be called > when an object has finished initializing. It cries out to be placed > in class Object, so that you can just send this message to the object > and let it take care of it. In this case, I don't even think the system > code should be refactored -- this is a great Smalltalk design the way > it is. Not having looked at SIXX, it is of course hard to answer the question concretely. However, it isn't exactly the first time this problem has come up and with a type-test this simply becomes: SIXX>>sendInitializeTo: anObject anObject isSixxObject ifTrue:[anObject sixxInitialize]. Nothing in this cries to be implemented in Object, except perhaps from the type test (which I have repeatedly admitted). > In practice, it has proven very valuable that Smalltalk modules are > allowed to modify the system classes. This is a dangerous thing to > do, of course, but I would really hate to handicap the above fine > packages just because of the *potential* for danger. Instead, we > should admit that inter-module conflicts exist, and deal with > them head-on, as they happen.... Well, go for it. We'll be heading another way. Cheers, - Andreas |
In reply to this post by Roel Wuyts
+ 1
this is why we need to work on that :) Giveme money :) Stef On 12 mars 07, at 22:31, Roel Wuyts wrote: > Indeed. I think we need both. In the same model. > > On 12 Mar 2007, at 12 March/08:32, Andreas Raab wrote: >> Roel Wuyts wrote: >>> Andreas, I prefer refactoring, but refactoring assumes a closed >>> world approach where you control all the pieces of the puzzle. >> >> I would call access to all pieces of the puzzle "open" not >> "closed" but be that as it may... >> >>> It simply is not always possible to refactor (because you do not >>> have the source, because you do not want to create a fork, >>> because you have other programs that absolutely rely on the old >>> behaviour, etc.). In that case extending the existing software >>> from within your own package helps, but should be used sparingly >>> for all the reasons you mention. >>> Note that a decent module system should support both. >> >> Which I have advocated earlier myself. I have never doubted that >> there are situation in which patching another module is >> advantageous and desirable. Which is why I don't understand why >> some people are so opposed to the idea of having the other end of >> the spectrum (isolation) available as well. >> >> Cheers, >> - Andreas >> > > > |
In reply to this post by Lex Spoon-3
Hi,
----- Original Message ----- From: "Lex Spoon" <[hidden email]> To: <[hidden email]> Sent: Monday, March 12, 2007 10:53 PM Subject: Re: Java's modules rock? (was Re: election details *PLEASE READ*) > Roel Wuyts <[hidden email]> writes: > > Andreas, I prefer refactoring, but refactoring assumes a closed world > > approach where you control all the pieces of the puzzle. > > > > It simply is not always possible to refactor (because you do not have > > the source, because you do not want to create a fork, because you > > have other programs that absolutely rely on the old behaviour, etc.). > > Exactly. It also assumes that even if you have the code, you can > convince the other guy to make the change. This is a significant > burden. You are better off if you can propose your module and then > let people try it. If it is popular, then the other guy will know > your code is not loopy and so will be more amenable to cooperating on > a refactoring. > > > Shout replaces the system text editor, which in my mind is an invasive > change that is just the sort of thing hard-shelled modules would be > likely to disallow. I can assure you, the behavior of a lot of things > changes when you have Shout loaded. There could be some confusion here. Although the base Shout package has no overrides, and hooks into AppRegistry, there are a number of optional Shout 'add-on' packages which are more intrusive, and therefore provide better examples :- For example, ShoutMonticello enables Shout in Monticello, and overrides MCTool>>textMorph: to force it to use MorphicTextEditor default , rather than PluggableTextMorph. Similarly, ShoutOmniBrowser, overrides MCDefinitionPanel>>morph to force the use of MorphicTextEditor default, instead of OBPluggableTextMorph. I don't l know if these add-ons are good, bad, or just ugly; I am neither defending nor promoting them. They are loaded in the squeak-dev images, which could give the impression that Shout changes many things. They are distributed as .mcz files, on SqueakMap and SqueakSource, mainly for convenience. They could just as easily be some changesets, downloadable from a Wiki page, or whatever. In that case would they still be 'packages', or just 'patches'? I hope this helps the conversation along, Cheers, Andy |
On Mar 13, 2007, at 10:27 , Andrew Tween wrote:
> For example, ShoutMonticello enables Shout in Monticello, and > overrides > MCTool>>textMorph: to force it to use MorphicTextEditor default , > rather than > PluggableTextMorph. > > Similarly, ShoutOmniBrowser, overrides MCDefinitionPanel>>morph to > force the use > of MorphicTextEditor default, instead of OBPluggableTextMorph. > [...] > They are distributed as .mcz files, on SqueakMap and SqueakSource, > mainly for > convenience. Indeed, "if you know what you are doing" this is one of the two ways you can handle this at the moment. The advantage of using a package that overrides something in another package is that the original package does not get "dirty", it can still be updated, and you can maintain the patch separately - but this is usually more than outweighed by the horrible mess you get when the clever system fails, which is more often the case than not. The other way is to just save your own version of the original package, and then remember to only ever "merge" upstream versions. The problem with this is that it's hard to still produce a clean new upstream version from your locally modified package - since MC is snapshot-based it does not know which patches belong to your local branch and should not be published. > They could just as easily be some changesets, downloadable from a > Wiki page, or whatever. In that case would they still be > 'packages', or just > 'patches'? That would be the worst of both worlds - but surely works, you just have to manually reapply the change after upgrading the package. - Bert - |
In reply to this post by stephane ducasse-2
Dylan was developed at Apple and highly influenced by
Bobrow/Kiczales/desRivieres', etc. pre-AOP work. It formalized the concept of sealing a domain against extension or replacement. http://www.opendylan.org/books/drm/Sealing It's all very nicely done, but is based on multiple-inheritance AND multi-method dispatch. It is not clear to me if applying this would be easier due to the simplicity of Smalltalk, or harder because of the lack of a simplifying higher-level abstraction (which sometimes makes it attractive for people to work around stuff in a more ad hoc but less "sealable" way). Curl is somewhat closer to Smalltalk in this respect. It abandons sealing in favor of specifying a version range in the code by which one module includes another. Internal renaming is used to allow multiple versions of the same module to be used by different parts of the same application.(I can't find a reference, but http://en.wikibooks.org/wiki/Curl#Version_numbers is a start.) In other words, it keeps old stuff working by not allowing you to change that which is already used underneath existing stuff. It is anti-OpenImplementation. I can't wait to see what the COLA folks come up with! -H stephane ducasse wrote: > **thanks** > I like this kind of discussions. (I hope to get someone working on > solution 3 but money is scarce :) > > Now about modules, I found several occasions (and this is also the idea > behing open implementation of kiczales > before they went in aop) is that the boundary of modules are often at > the wrong level of abstraction since > sometimes you want to be able to change deep implementation points. So > in some cases (network for example) > people do not want to use library since they lose their ability to > control low level. > Some people pointed to me ml functors with the experience that it was > powerful but that often people were > using functors on functors on functors leading to system that noone can > understand. > > Stef > > On 10 mars 07, at 22:16, Andreas Raab wrote: > >> stephane ducasse wrote: >>> Did you encounter cases where you would have like to have different >>> versions of the same component/modules running in the same image. >> >> Sure. Consider Croquet: It relies on replicated computation which >> means that the replicated islands must have identical code based to >> have the same behavior. But what happens when you link to a space >> which uses a different (older or newer) version of a module that is >> already loaded in the space you are in? As far I can see there are >> only three options:] >> >> 1. Don't ever allow it. That's our current solution, i.e. all spaces >> linked together must use the same code base. For the obvious reasons >> this is neither particularly scalable nor desirable. >> >> 2. Force migration of "older" spaces. This may be an acceptable >> solution if the number of spaces linked together is relatively small. >> However it has the disadvantage that you create "waves" of updates >> since participants are linked together in unforeseen ways (compare >> this to a WWW where each web page can only be linked to another >> webpage of the same version and where upgrading one would implicitly >> require upgrade all the ones it links to - I think you can see the >> basic problem with the approach). >> >> 3. Have these modules sit side-by-side. In reality, this is the only >> scalable, secure and desirable solution. >> >> Cheers, >> - Andreas >> >> > > -- Howard Stearns University of Wisconsin - Madison Division of Information Technology mailto:[hidden email] jabber:[hidden email] voice:+1-608-262-3724 |
thanks for the pointers :)
Stef > Dylan was developed at Apple and highly influenced by Bobrow/ > Kiczales/desRivieres', etc. pre-AOP work. Art of MetaObject protocol and open-Implementation are cool :) > > It formalized the concept of sealing a domain against extension or > replacement. > http://www.opendylan.org/books/drm/Sealing > > It's all very nicely done, but is based on multiple-inheritance AND > multi-method dispatch. It is not clear to me if applying this would > be easier due to the simplicity of Smalltalk, or harder because of > the lack of a simplifying higher-level abstraction (which sometimes > makes it attractive for people to work around stuff in a more ad > hoc but less "sealable" way). > > Curl is somewhat closer to Smalltalk in this respect. It abandons > sealing in favor of specifying a version range in the code by which > one module includes another. Internal renaming is used to allow > multiple versions of the same module to be used by different parts > of the same application.(I can't find a reference, but http:// > en.wikibooks.org/wiki/Curl#Version_numbers is a start.) In other > words, it keeps old stuff working by not allowing you to change > that which is already used underneath existing stuff. It is anti- > OpenImplementation. > > I can't wait to see what the COLA folks come up with! > > -H > > stephane ducasse wrote: >> **thanks** >> I like this kind of discussions. (I hope to get someone working on >> solution 3 but money is scarce :) >> Now about modules, I found several occasions (and this is also the >> idea behing open implementation of kiczales >> before they went in aop) is that the boundary of modules are often >> at the wrong level of abstraction since >> sometimes you want to be able to change deep implementation >> points. So in some cases (network for example) >> people do not want to use library since they lose their ability to >> control low level. >> Some people pointed to me ml functors with the experience that it >> was powerful but that often people were >> using functors on functors on functors leading to system that >> noone can understand. >> Stef >> On 10 mars 07, at 22:16, Andreas Raab wrote: >>> stephane ducasse wrote: >>>> Did you encounter cases where you would have like to have >>>> different versions of the same component/modules running in the >>>> same image. >>> >>> Sure. Consider Croquet: It relies on replicated computation which >>> means that the replicated islands must have identical code based >>> to have the same behavior. But what happens when you link to a >>> space which uses a different (older or newer) version of a module >>> that is already loaded in the space you are in? As far I can see >>> there are only three options:] >>> >>> 1. Don't ever allow it. That's our current solution, i.e. all >>> spaces linked together must use the same code base. For the >>> obvious reasons this is neither particularly scalable nor desirable. >>> >>> 2. Force migration of "older" spaces. This may be an acceptable >>> solution if the number of spaces linked together is relatively >>> small. However it has the disadvantage that you create "waves" of >>> updates since participants are linked together in unforeseen ways >>> (compare this to a WWW where each web page can only be linked to >>> another webpage of the same version and where upgrading one would >>> implicitly require upgrade all the ones it links to - I think you >>> can see the basic problem with the approach). >>> >>> 3. Have these modules sit side-by-side. In reality, this is the >>> only scalable, secure and desirable solution. >>> >>> Cheers, >>> - Andreas >>> >>> > > -- > Howard Stearns > University of Wisconsin - Madison > Division of Information Technology > mailto:[hidden email] > jabber:[hidden email] > voice:+1-608-262-3724 > > |
In reply to this post by Howard Stearns
>>> >>> 3. Have these modules sit side-by-side. In reality, this is the >>> only scalable, secure and desirable solution. Andreas I thinking in the tram about that. it seems to imply that you would have to "reimport" in the old client using the old version to the new version of the module to support migration and get the new client. Is it what you think? Stef |
In reply to this post by Andreas.Raab
Andreas Raab <[hidden email]> writes:
> Lex Spoon wrote: > > Shout replaces the system text editor, which in my mind is an invasive > > change that is just the sort of thing hard-shelled modules would be > > likely to disallow. > > Not at all. Shout uses an API (AppRegistry) that is specifically > provided for clients so they can pick up an alternative text editor if > they choose to. No module system in the world would disallow > interaction that is based on an explicitly provided API. Besides why > do you call the change "invasive"? It does not touch any code in the > system text editor, all it does is using an API that was explicitly > provided for that purpose. Why is that "invasive"? I am thinking of the fact that some versions of Shout have messed up Celeste's message pane. It was no big deal, but the modules did interfere with each other. But it sounds like Shout isn't a great example. How about NewCompiler? As of version 117, it still had a lot of additions to the system. I would argue this is fine; if someone is proposing a new compiler, they do not need to coordinate a bunch of hooks in the system for replacing all the odds and ends that this would entail. At least for getting started, we may as well have people post the version that includes overrides and go from there. Sealed modules, for all of their benefits, would seemingly disallow this approach. > > There are plenty of other examples, though. Extreme examples would be > > Zurgle and Genie. These old packages changed various classes in > > Morphic when they were loaded. Interestingly, one became standard, > > and the other faded and stopped being maintained. Open modules worked > > well for these cases; they let the proponents post their code for > > people to play with, without immediately needing to get the standard > > Morphic classes refactored to suit them. And anyway, they were both > > probably lobbying for standard inclusion, anyway, so refactoring > > hooks for them would be superfluous overengineering. > > Oh, that's cheap. It's not even worth responding. I meant nothing cheap here. These are outrageously cool modules which made system changes when loaded. If you think open modules are evil, how would you deal with add-ons like these two? > > Those are extreme examples. There are a lot of intermediate examples, > > too, where you want to add a few thing to Object to make everything go > > smoothly. Look at the code for GOODS or SIXX sometime. GOODS adds > > "isGoodsImmutable", which I guess you would say should be supported > > through a type-check mechanism. Fair enough. How about SIXX's addition > > of Object>>sixxInitialize ? This method is supposed to be called > > when an object has finished initializing. It cries out to be placed > > in class Object, so that you can just send this message to the object > > and let it take care of it. In this case, I don't even think the system > > code should be refactored -- this is a great Smalltalk design the way > > it is. > > Not having looked at SIXX, it is of course hard to answer the question > concretely. However, it isn't exactly the first time this problem has > come up and with a type-test this simply becomes: > > SIXX>>sendInitializeTo: anObject > anObject isSixxObject ifTrue:[anObject sixxInitialize]. And how do you define isSixxObject? I think you are stuck shifting the potential conflict from place to place. You can say that SixxObject is a type, and you'll use isKindOf:, but now the type is in a global namespace. So how do you keep the global type name from confliting between modules? Maybe you say global names are hierarchical, but even that is not an absolute guarantee that the names will stay unique. Use DNS names? That only works until two college students use their department's DNS name. The only way I see to take the extreme stance is to abandon all global namespaces and have explicit imports and exports and explicit link scripts that tie a group of modules together. Putting these link scripts together appears to be rather a lot of work, though maybe a system can be designed that both does it and is not too too onerous. So, short of some radical change like this, it seems best to allow modules to change things in other modules, especially relatively safe changes like adding a method to another class. I do not mean it has to be easy or encouraged, but it should not be too onerous for people who really want to do it. It allows a lot more packages to be proposed and tried. Lex |
Free forum by Nabble | Edit this page |