Matthew Fulmer wrote:
>> self system debug: true >> >> I got fed up with that myself today and made debug mode the >> default. I havn't committed that change yet. > > Committed: SystemEditor-Squeak-mtf.160 After loading that version and executing: ed := SystemEditor new. (ed at: #SimpleButtonMorph) addInstVarName: #foo. ed commitWithProgress. nothing at all happens, e.g., no variable gets added to SimpleButtonMorph (this is in 3.10.7159 in case it matters). The same for mtf.161 which I tried as well. Is there something resembling a "stable" version of SystemEditor that I can use to try some of the harder tasks on? The experience so far is a bit unsatisfying given that SE doesn't execute basic tasks correctly. Cheers, - Andreas |
Okay, I'm slowly getting there. It seems like updating SystemEditor in
MC in 3.10 somehow broke it - some methods were simply referring to the wrong ivars which caused SE not to work at all. Recompiling the SE packages fixed that. Secondly, the issue I was seeing with the iVars being incorrect are one of the subtleties that SE currently doesn't correctly deal with. Here is an illustration: testCleanupOfOldInstances "Ensure that old instance are cleaned up properly" instance := CleanupTestClass new. Smalltalk garbageCollect. "for easier results make it old" self assert: CleanupTestClass instanceCount = 1. ed := SystemEditor new. (ed at: #CleanupTestClass) addInstVarName: #whatever. ed commit. self assert: CleanupTestClass instanceCount = 1. ed := SystemEditor new. (ed at: #CleanupTestClass) removeInstVarName: #whatever. ed commit. self assert: CleanupTestClass instanceCount = 1. The problem is that since #become: changes class pointers you *must* clean out the old instances or otherwise they'll be completely and utterly broken when you finally #become: the classes itself. This can be achieved by placing a strategic full GC in the right place in the migration process (I'm not sure where that would be in SE but probably somewhere in the migration transaction). Cheers, - Andreas |
In reply to this post by Vassili Bykov-2
> So you are lamenting loss of encapsulation (a restrictive feature) in
> the first paragraph, and decrying loss of freedom to restrictive > features in the second. Come on, pick one. Because I consider encapsulation something that exists between objects, not between super and subclass. I don't consider that a conflict, interesting that you do. > If you don't want the > author of a class deciding how you might decide to use it, how can you > put up with him deciding what instance variables are off-limits and > have no public accessors? Again, the object class divide; he can't, in Smalltalk, restrict me from seeing instance variables if I subclass his class. I like it this way. When I'm building a new class it's up to me whether to choose to use inheritance or not and if I choose to do so it's because I want to share code or extend or specialize that class and I want direct access to anything in that superclass. My class is not his class and if I do something that makes my classes instances misbehave that's my problem, not his. The public interface of instances of his objects however, is his problem and he has every right to encapsulate and protect the implementation of his instances. There simply is a difference, to me at least, between using someone else's objects, and using someone else's classes as a template to build my own objects. I accept encapsulation as beneficial and necessary in the former case but as harmful and restrictive in the latter. I base this judgment on the vocabulary I find myself muttering in each case, usually profanity in the latter case while I hunt down source code to change the original authors access modifiers. > Indeed what I had in mind were Newspeak-style access modifiers > combined with message-based slot access. Their combination in fact > improves encapsulation. And no, they don't lead to final classes. > > Cheers, > > --Vassili They certainly start down that road, final and sealed are just as much access modifiers as public, private, or protected; however, if not applied zealously and taken too far (i.e. final classes), I agree it's not a bad solution. I would prefer not to have two ways to access instances vars so if protected accessors were the solution I'd want them to replace all direct instance variable access, even within a single class so slots make perfect sense. But at this point, we're not really talking about Smalltalk any more. I won't pretend to be a language designer or say I know what the perfect balance of features is, but I rather like the balance Smalltalk struck with no access modifiers, public methods, protected instances variables, and trust in the programmer. Ramon Leon http://onsmalltalk.com |
In reply to this post by Andreas.Raab
On 26-Nov-08, at 2:53 PM, Andreas Raab <[hidden email]> wrote: > Hi Colin - > > I was looking over SystemEditor and one thing that really surprised > me was the use of ClassEditors as proxies. What is the reasoning > behind it? It makes the design difficult to understand and extremely > hard to debug - I gave up trying to find out what causes the issue > with class migration when I effectively couldn't debug the editors > since all they would show me were those pretend-classes. Is there > some sort of debug mode to turn off all that evil magic? ;-) The purpose of SystemEditor is to provide a way to atomically apply changes to the system, using an interface identical to the reflective interface already in use. The proxies provide protocol compatibility, while recording the changes, that need to be made. Then, when it's time to commit, it does all the class building, compiling, instance migration and so on, and finally installs it atomically with a mass become. So the design is aimed at providing easy-to-adopt atomic updates. The increase in performance is icing, but it makes sense, I guess. Making a change involves a certain amount of overhead, and making the changes one by one incurs that overhead for each change. SystemEditor aggregates changes and can amortize the overhead across several changes. Monticello 2 benefits from this even more than Monticello1, because it deals with instance variables individually, and so incurs migration overhead for each ivar, rather than for each class. I hear you though. If you think ClassEditor is evil, look at MetaclassEditor. ;-) Colin |
In reply to this post by Ramon Leon-5
2008/11/27 Ramon Leon <[hidden email]>:
>> So you are lamenting loss of encapsulation (a restrictive feature) in >> the first paragraph, and decrying loss of freedom to restrictive >> features in the second. Come on, pick one. > > Because I consider encapsulation something that exists between objects, not > between super and subclass. I don't consider that a conflict, interesting > that you do. > >> If you don't want the >> author of a class deciding how you might decide to use it, how can you >> put up with him deciding what instance variables are off-limits and >> have no public accessors? > > Again, the object class divide; he can't, in Smalltalk, restrict me from > seeing instance variables if I subclass his class. I like it this way. > When I'm building a new class it's up to me whether to choose to use > inheritance or not and if I choose to do so it's because I want to share > code or extend or specialize that class and I want direct access to anything > in that superclass. My class is not his class and if I do something that > makes my classes instances misbehave that's my problem, not his. > > The public interface of instances of his objects however, is his problem and > he has every right to encapsulate and protect the implementation of his > instances. There simply is a difference, to me at least, between using > someone else's objects, and using someone else's classes as a template to > build my own objects. I accept encapsulation as beneficial and necessary in > the former case but as harmful and restrictive in the latter. > > I base this judgment on the vocabulary I find myself muttering in each case, > usually profanity in the latter case while I hunt down source code to change > the original authors access modifiers. > >> Indeed what I had in mind were Newspeak-style access modifiers >> combined with message-based slot access. Their combination in fact >> improves encapsulation. And no, they don't lead to final classes. >> >> Cheers, >> >> --Vassili > > They certainly start down that road, final and sealed are just as much > access modifiers as public, private, or protected; however, if not applied > zealously and taken too far (i.e. final classes), I agree it's not a bad > solution. I would prefer not to have two ways to access instances vars so > if protected accessors were the solution I'd want them to replace all direct > instance variable access, even within a single class so slots make perfect > sense. But at this point, we're not really talking about Smalltalk any > more. > > I won't pretend to be a language designer or say I know what the perfect > balance of features is, but I rather like the balance Smalltalk struck with > no access modifiers, public methods, protected instances variables, and > trust in the programmer. > Concerning security models and principles it is based upon, i very like a simple & powerful security model used in E (Erights). >From http://www.erights.org/elib/capability/ode/overview.html ---- Capability Security. The Granovetter Operator becomes a security primitive given the following constraint: If Bob does not already have a reference to Carol, Bob can only come to have a reference to Carol if a third party, such as Alice, * already has a reference to Carol, and * already has a reference to Bob, and * voluntarily decides to share with Bob her reference to Carol. Adding this property to an object system transforms it into a capability system. In a capability system, only connectivity begets connectivity. In a capability system, an object's authority to affect the world outside itself is determined solely by what references it holds, since the only way the object can cause an external effect is to send a message via one of these references. Consequently, the mechanics of reference-passing determine how authority can change over time. ---- Its easy to show, that access modifiers or class sealing is not the answer to security. Simply do not give away an object references to untrusted code which would allow it to operate directly with critical system resources. In short, a principle is very simple: you can't break things which you cannot reach or see. > Ramon Leon > http://onsmalltalk.com > -- Best regards, Igor Stasenko AKA sig. |
In reply to this post by Tony Garnock-Jones-2
El 11/26/08 2:53 PM, "Tony Garnock-Jones" <[hidden email]> escribió: > ***** I'd really appreciate an extended essay -- a textbook? a > manifesto? -- from those who properly grok it (i.e. Alan and those at > VPRI), aimed at helping out those who'd like to: a kind of little-step > by little-step introduction to weaning people off their current mindset > and helping them explore the subtleties of the new way of looking at > things. Something akin in spirit, perhaps, to Drexler's Engines of > Creation. ***** Then you should look material of Alejandro Reimondo . He is talking and writing about Objects and "Beyond Objects" (perdon Ale) all this years. He have his group for discuss "Alejandro F. Reimondo" <[hidden email]> Edgar |
In reply to this post by Colin Putney
Colin, Matthew and Andreas. Can I beg doing a swiki page about SystemEditor , with all you was discussing here ? Tutorials ? I waiting from Ralph times before the end of 3.10 this important tool was finished. Seems the long wait is near to end , congrats to all :=) Edgar |
In reply to this post by Colin Putney
Colin Putney wrote:
> The purpose of SystemEditor is to provide a way to atomically apply > changes to the system, using an interface identical to the reflective > interface already in use. The proxies provide protocol compatibility, > while recording the changes, that need to be made. But why do you need proxying and protocol compatibility? The only reason I've ever found was to make sure existing tools (browser etc) can work with those proxies. Is this what you're after, e.g., have a browser with a "commit" button which then does all the changes atomically? If not, I'm not sure what you need the proxying / protocol compatibility for. > I hear you though. If you think ClassEditor is evil, look at > MetaclassEditor. ;-) Heh. I knew what I was in for when ClassEditor class>>new said something along the lines of "MetaclassEditor new new" ;-) Cheers, - Andreas |
On 27-Nov-08, at 1:28 AM, Andreas Raab wrote: > But why do you need proxying and protocol compatibility? The only > reason I've ever found was to make sure existing tools (browser etc) > can work with those proxies. Is this what you're after, e.g., have a > browser with a "commit" button which then does all the changes > atomically? If not, I'm not sure what you need the proxying / > protocol compatibility for. Well, yeah. My immediate goal was atomic loads for MC2, which was already working non-atomically using the existing protocol. It wasn't completely trivial to make MC2 use SystemEditor, but it was pretty easy. Now that the work has been done, turning atomic loading on or off is a one line change. It could be a preference. But beyond that, the barrier to adoption to these sorts of things is always tool support. The browser is actually the least interesting tool in this case, since it makes one change at a time, and you usually want them applied immediately anyway. It might be useful for especially fiddly stuff like hacking on Compiler, but that's pretty rare. I was actually more interested in tools that load code in bulk: MC1, MC2, file-in, SAR, SqueakMap etc. The alternative would have been a protocol with methods like #classNamed:addInstVar:, written as part of MC2 rather than as an independent package. That could still work, if compatibility turns out to be more trouble than it's worth. Colin |
In reply to this post by Ramon Leon-5
On Wed, Nov 26, 2008 at 8:42 PM, Ramon Leon <[hidden email]> wrote:
>> So you are lamenting loss of encapsulation (a restrictive feature) in >> the first paragraph, and decrying loss of freedom to restrictive >> features in the second. Come on, pick one. > > Because I consider encapsulation something that exists between objects, not > between super and subclass. I don't consider that a conflict, interesting > that you do. Then you don't seem to realize that we work with classes and their code, not objects. It's code dependencies that translate into maintenance. As for objects, their composition from class blueprints is not necessarily as unambiguous as you are used to. In Newspeak, for example, you can't always point and say, "this will be the superclass of this guy" because the superclass is late-bound. You can't even compile that sort of thing easily unless you take messages further, to communicate within objects as well as between them. I view that information hiding as beneficial enough to even overlook the sacrifice encapsulation in its naive understanding (see below what I really think about access modifiers). Encapsulation is an interesting thing in that popular literature promotes a very narrow view of it. It often starts with a reasonable explanation of information hiding as a noble architectural principle, then degrades into "so in a nutshell, store your data in private fields". That confuses information hiding with security. Information hiding helps structure code, security when it's inappropriate only gets in the way. There are languages where all object slots are accessible--CLOS, for example. I'd like to hear a C++ programmer declare CLOS a non-OO language because it lacks "encapsulation". This narrow view is the evidence of how little the mainstream gets OO. The mechanism for encapsulation in its true sense is so ingrained in Smalltalk you can't take it out--it's messages, with the late binding of a name to its interpretation. There is no other way to communicate with an object. Too bad for C++, but that is what OO is about, not "encapsulation, inheritance, polymorphism". Message-based computation enables information hiding and promotes weaker code dependencies. And now I can admit that I view access modifiers for slot accessor messages as more of a political tool to shut up those who would cry "aha, no encapsulation!" as soon as they saw messages used for slot access. I don't think they are an important safeguard preventing horrors from happening. Here is what I find interesting about the belief that encapsulation is critically flawed without object data hidden away. There is enough Smalltalk code out there written in variable-exposing style. Large complex systems have been built in CLOS with its wide open object slots. Where are the real horror stories about this practice? I mean real horror--not "I remember there was this bug once..." but rather "...and man, we had to spend weeks fixing that crap before it started working". All you hear are speculations how exposed variables are bad because encapsulation is good. That sounds to me like "dynamic typing is dangerous because you get runtime errors, and static typing would catch at least some of those". An intellectual bogeyman. It may sound reasonable as an isolated statement, but anyone with some practical experience will know better. Having open slots at your disposal is one thing, using that access indiscriminately to hurt yourself is a completely different one. One last point, the most likely reason instance variables are the way they are is because it was a necessary performance compromise for the '70s hardware. No reason to consider that as some sort of heavenly harmony, even if you are used to it. Cheers, --Vassili |
In reply to this post by Igor Stasenko
On Wed, Nov 26, 2008 at 9:52 PM, Igor Stasenko <[hidden email]> wrote:
> Its easy to show, that access modifiers or class sealing is not the > answer to security. > Simply do not give away an object references to untrusted code which > would allow it to operate directly with critical system resources. > > In short, a principle is very simple: you can't break things which you > cannot reach or see. Yes, and also as I just wrote in another post, it's a mistake to even expect that access modifiers are there to provide security (despite some unfortunate examples in mainstream literature). They are artifacts that work at completely different architectural levels. Access modifiers are there to ensure certain invariants about the code. Thus they are a code-level trust structuring mechanism, not object-level trust structuring that capabilities build. Cheers, --Vassili |
In reply to this post by Nicolas Cellier-3
Jecel Assumpcao Jr a écrit :
> nicolas cellier wrote: >> James Foster a écrit : >>> On Nov 25, 2008, at 7:45 PM, Igor Stasenko wrote: >>>> My understanding of inheritance is different, in short: >>>> A subclass of particular class is a _specialization_ of base class, >>>> not _expansion_. >>> In this context, I sometimes wonder if Square should inherit from >>> Rectangle (a specialization in which width and height are equal), or >>> Rectangle should inherit from Square (adding an instance variable). Am I >>> right that you would have Square inherits from Rectangle (Square being >>> more specialized)? But then it feels like we are wasting an instance >>> variable (since Rectangle would have two). >> Beware, you're dangerously sliping to multiple inheritance because your >> Square might also be a lozenge :) > > With the Rectangle as subclass of Square option this wouldn't be a > problem - you would just have two different subclasses of Square. > > Could Rectangle be a subclass of Square? Sure: > > - Square instance variables: center, size, orientation > > - Rectangle adds this instance variable: aspectRatio > Following proposition does not seem to match what we learned at school (Rectangle isKindOf: Square) -> true But with a different POV, yes, a Rectangle isKindOf (degenerated) Square, a flatten one. So why not. However, the question, apart inst vars is what methods/algorithm should/could be inherited. It seems to me that Square being a Rectangle could safely inherit all Rectangle methods. The reverse is not necessarily true, and this scheme would force to re-examine method by method which one to override because Square assumption is not true anymore (think of a method exploiting orthogonal diagonals properties for example). That is somehow fragile. Each time you add a method to Square, you must think in term of Rectangle or Lozenge... That breaks some kind of encapsulation no? > We can make Ellipse a subclass of Circle using the same style. We can > even have an #aspectRatio method in Square and Circle which always > returns 1 and then we can move some of the more general code up in the > classes hierarchy if we want to. > > For raster graphics it is convenient to define Rectangles as always > parallel to the screen axis so that just two points are enough to fully > identify them. Perhaps calling them RasterRects instead would have made > us think more clearly about them. We later moved to vector graphics > (Balloon) but were stuck with the historic baggage. > > -- Jecel > P.S.: I am aware that even in this scheme you might want Parallelogram > to inherit from both Rectangle and Lozenge (actually, Rhombus is more > generic) and then you have the multiple inheritance problem again. Which > is what Traits are for... > > > Of course. Nicolas |
In reply to this post by Vassili Bykov-2
> On Wed, Nov 26, 2008 at 8:42 PM, Ramon Leon
> <[hidden email]> wrote: > >> So you are lamenting loss of encapsulation (a restrictive > feature) in > >> the first paragraph, and decrying loss of freedom to restrictive > >> features in the second. Come on, pick one. > > > > Because I consider encapsulation something that exists > between objects, not > > between super and subclass. I don't consider that a > conflict, interesting > > that you do. > > Then you don't seem to realize that we work with classes and their > code, not objects. It's code dependencies that translate into > maintenance. As for objects, their composition from class blueprints > is not necessarily as unambiguous as you are used to. In Newspeak, for > example, you can't always point and say, "this will be the superclass > of this guy" because the superclass is late-bound. You can't even > compile that sort of thing easily unless you take messages further, to > communicate within objects as well as between them. I view that > information hiding as beneficial enough to even overlook the sacrifice > encapsulation in its naive understanding (see below what I really > think about access modifiers). > > Encapsulation is an interesting thing in that popular literature > promotes a very narrow view of it. It often starts with a reasonable > explanation of information hiding as a noble architectural principle, > then degrades into "so in a nutshell, store your data in private > fields". That confuses information hiding with security. Information > hiding helps structure code, security when it's inappropriate only > gets in the way. There are languages where all object slots are > accessible--CLOS, for example. I'd like to hear a C++ programmer > declare CLOS a non-OO language because it lacks "encapsulation". > > This narrow view is the evidence of how little the mainstream gets OO. > The mechanism for encapsulation in its true sense is so ingrained in > Smalltalk you can't take it out--it's messages, with the late binding > of a name to its interpretation. There is no other way to communicate > with an object. Too bad for C++, but that is what OO is about, not > "encapsulation, inheritance, polymorphism". Message-based computation > enables information hiding and promotes weaker code dependencies. > > And now I can admit that I view access modifiers for slot accessor > messages as more of a political tool to shut up those who would cry > "aha, no encapsulation!" as soon as they saw messages used for slot > access. I don't think they are an important safeguard preventing > horrors from happening. > > Here is what I find interesting about the belief that encapsulation is > critically flawed without object data hidden away. There is enough > Smalltalk code out there written in variable-exposing style. Large > complex systems have been built in CLOS with its wide open object > slots. Where are the real horror stories about this practice? I mean > real horror--not "I remember there was this bug once..." but rather > "...and man, we had to spend weeks fixing that crap before it started > working". > > All you hear are speculations how exposed variables are bad because > encapsulation is good. That sounds to me like "dynamic typing is > dangerous because you get runtime errors, and static typing would > catch at least some of those". An intellectual bogeyman. It may sound > reasonable as an isolated statement, but anyone with some practical > experience will know better. Having open slots at your disposal is one > thing, using that access indiscriminately to hurt yourself is a > completely different one. > > One last point, the most likely reason instance variables are the way > they are is because it was a necessary performance compromise for the > '70s hardware. No reason to consider that as some sort of heavenly > harmony, even if you are used to it. > > Cheers, > > --Vassili Definitely some food for thought. Ramon Leon http://onsmalltalk.com |
In reply to this post by Andreas.Raab
On Wed, Nov 26, 2008 at 07:45:14PM -0800, Andreas Raab wrote:
> Secondly, the issue I was seeing with the iVars being incorrect are one > of the subtleties that SE currently doesn't correctly deal with. Here is > an illustration: > > testCleanupOfOldInstances > "Ensure that old instance are cleaned up properly" > instance := CleanupTestClass new. > Smalltalk garbageCollect. "for easier results make it old" > > self assert: CleanupTestClass instanceCount = 1. > > ed := SystemEditor new. > (ed at: #CleanupTestClass) addInstVarName: #whatever. > ed commit. > > self assert: CleanupTestClass instanceCount = 1. > > ed := SystemEditor new. > (ed at: #CleanupTestClass) removeInstVarName: #whatever. > ed commit. > > self assert: CleanupTestClass instanceCount = 1. > > The problem is that since #become: changes class pointers you *must* > clean out the old instances or otherwise they'll be completely and > utterly broken when you finally #become: the classes itself. This can be > achieved by placing a strategic full GC in the right place in the > migration process (I'm not sure where that would be in SE but probably > somewhere in the migration transaction). You are right. There is no equivalant to the garbageCollect in ClassBuilder >> migrate:to:. The best place to put it would probably be at the end of SystemEditor>>commit -- Matthew Fulmer -- http://mtfulmer.wordpress.com/ |
On Sat, Nov 29, 2008 at 08:26:24PM -0700, Matthew Fulmer wrote:
> You are right. There is no equivalant to the garbageCollect in > ClassBuilder >> migrate:to:. The best place to put it would > probably be at the end of SystemEditor>>commit fixed in 262. thanks. -- Matthew Fulmer -- http://mtfulmer.wordpress.com/ |
In reply to this post by Bert Freudenberg
On Thu, Nov 27, 2008 at 3:49 AM, Bert Freudenberg <[hidden email]> wrote:
> > On 26.11.2008, at 22:38, Ties Stuij wrote: > >> On Thu, Nov 27, 2008 at 3:54 AM, Jecel Assumpcao Jr <[hidden email]> >> wrote: >>> >>> Tony Garnock-Jones wrote: >>>> >>>> Bert Freudenberg wrote: >>>>> >>>>> Just a meta remark - I find it highly amusing how people dissect the >>>>> Gospel of Alan, even interpreting it literally. He must get quite a >>>>> chuckle from that ;) >>>> >>>> Well I hope so! :-) >>> >>> Given how happy he said he was to not have any disciples, he might be >>> less than amused to find out otherwise ;-) >>> >>> Going to the other extreme, where everyone's opinion is equally valid, >>> leads to situations like a guy explaining to me on comp.lang.lisp that >>> multiple dispatch is the most important feature of OOP and so CLOS and >>> C++ are true OO languages but Smalltalk is not. >>> >>>> >>>> http://groups.google.com/group/comp.lang.lisp/browse_thread/thread/b2aa1842ccb7d7c/134456502780e63f?hl=en&lnk=gst&q=jecel#134456502780e63f >> >> I know I shouldn't react, but could you just dissect for me how Alan's >> post, either the one before or the one after the post of yourself you >> linked here, makes the point you're suggesting him to be making? >> >> Is it the 'I've no idea where I'm going with this.' part perhaps? > > > I know I shouldn't respond, but did you read further up in the thread, where > Alan (Crowe) described how even the "simplest" things are impossible without > multiple dispatch, which made him despise Smalltalk on his first encounter, > an event he recites quite colorfully, with phrases like "I found this > incomprehensibly awful. It completely destroyed the object metaphor. [...] > I fled in horror from this hideous, mutilating language." There you go, proof I shouldn't have reacted. That sounded a lot more partisan and inflammatory. As we have come to expect from the cesspool that is c.l.l.. One should put a big lid on it, and not open it for a thousand years. Its noise-creating powers has even spilled over to squeak-dev, and here's another post to prove that point. Totally out of my control of course... /Ties |
Free forum by Nabble | Edit this page |