For people who think that we should not revise the class/metaclass
coupling in Squeak, just ignore this topic and consider it as a rant :) For those, who interested why i think its not a perfect from object-oriented point of view, continue reading. Ok. Lets start from basics. A classes, in smalltalk is a first class objects, which one of its strong sides, comparing to other languages. Since each object has a class, we also need an object which reflecting the class itself, and hence the metaclass. But then, each class could have as many instances as it likes to, isnt? But here the contradiction, which drives me nuts, when i looking at Metaclass definition - 'thisClass' ivar. This implies that any metaclass could have only a single instance - class. Metaclass>>new "The receiver can only have one instance. Create it or complain that one already exists." thisClass class ~~ self ifTrue: [^thisClass := self basicNew] ifFalse: [self error: 'A Metaclass should only have one instance!'] but hey.. what you suppose to do with things like: SomeClass clone ? I am trying to understand, why do we need this inconsistency by enforcing such a rigid rule. Like, how often you may need to determine a 'sole' instance of the class, or all instances? And why it needs to be so fast by keeping a direct reference to it? System browser could live well without it. Altering the metaclass definition? Well, iterate over all instances indiscriminately - using same mechanism as usual class doing for own instances. So, it is strange to me, why do we need such tight coupling.. Is anyone having insights about it? -- Best regards, Igor Stasenko AKA sig. |
If you haven't done this already, you should look up Actalk, which was
a version of Smalltalk that let you have many classes with the same metaclass. http://map.squeak.org/package/19ae332d-1111-4131-8b56-1fd7e9d2b35f I never used Actalk, I just read the papers. It was an interesting and worthwhile experiment, but I wasn't convinced that the change was worthwhile. But perhaps we just need to figure out more to do with it. What you are saying is a little different. You are just complaining about hardcoding the assumption that each clas has a unique metaclass. All you are really asking is to get rid of the "thisClass" variable. I don't see any harm in that. I bet that "new" is rarely called more than once on any metaclass, and that one time is during the creation of the class/metaclass pair. The bigger issue is that when you evaluate and print the expression "Object class", what happens is that it computes the metaclass and then asks the metaclass to print itself, which it does by fetching the name of its sole instance and appending " class" to it. In other words, a metaclass does not have a name, but derives its name from the name of its sole instance. But this doesn't have to be fast, either. You could call allInstances to find out the instance and get its name. My guess is that it would hardly be noticeable. Making this change would not cause metaclasses to have more than one instance, but would make it easier for people to change things so it would. -Ralph |
2009/12/8 Ralph Johnson <[hidden email]>:
> If you haven't done this already, you should look up Actalk, which was > a version of Smalltalk that let you have many classes with the same > metaclass. > > http://map.squeak.org/package/19ae332d-1111-4131-8b56-1fd7e9d2b35f > > I never used Actalk, I just read the papers. It was an interesting > and worthwhile experiment, but I wasn't convinced that the change was > worthwhile. But perhaps we just need to figure out more to do with > it. > > What you are saying is a little different. You are just complaining > about hardcoding the assumption that each clas has a unique metaclass. > All you are really asking is to get rid of the "thisClass" variable. > I don't see any harm in that. I bet that "new" is rarely called more > than once on any metaclass, and that one time is during the creation > of the class/metaclass pair. The bigger issue is that when you > evaluate and print the expression "Object class", what happens is that > it computes the metaclass and then asks the metaclass to print itself, > which it does by fetching the name of its sole instance and appending > " class" to it. In other words, a metaclass does not have a name, but > derives its name from the name of its sole instance. But this doesn't > have to be fast, either. You could call allInstances to find out the > instance and get its name. My guess is that it would hardly be > noticeable. > My own guess is that there would be a noticeable down speed in code management tools (Monticello & al). Nicolas > Making this change would not cause metaclasses to have more than one > instance, but would make it easier for people to change things so it > would. > > -Ralph > > |
2009/12/8 Nicolas Cellier <[hidden email]>:
> 2009/12/8 Ralph Johnson <[hidden email]>: >> If you haven't done this already, you should look up Actalk, which was >> a version of Smalltalk that let you have many classes with the same >> metaclass. >> >> http://map.squeak.org/package/19ae332d-1111-4131-8b56-1fd7e9d2b35f >> >> I never used Actalk, I just read the papers. It was an interesting >> and worthwhile experiment, but I wasn't convinced that the change was >> worthwhile. But perhaps we just need to figure out more to do with >> it. >> >> What you are saying is a little different. You are just complaining >> about hardcoding the assumption that each clas has a unique metaclass. >> All you are really asking is to get rid of the "thisClass" variable. >> I don't see any harm in that. I bet that "new" is rarely called more >> than once on any metaclass, and that one time is during the creation >> of the class/metaclass pair. The bigger issue is that when you >> evaluate and print the expression "Object class", what happens is that >> it computes the metaclass and then asks the metaclass to print itself, >> which it does by fetching the name of its sole instance and appending >> " class" to it. In other words, a metaclass does not have a name, but >> derives its name from the name of its sole instance. But this doesn't >> have to be fast, either. You could call allInstances to find out the >> instance and get its name. My guess is that it would hardly be >> noticeable. >> > > My own guess is that there would be a noticeable down speed in code > management tools (Monticello & al). > > Nicolas > Posted too fast... Beside, if it has several instances, then why insisting on giving a name related to a specific instance ? Nicolas >> Making this change would not cause metaclasses to have more than one >> instance, but would make it easier for people to change things so it >> would. >> >> -Ralph >> >> > |
2009/12/8 Nicolas Cellier <[hidden email]>:
> 2009/12/8 Nicolas Cellier <[hidden email]>: >> 2009/12/8 Ralph Johnson <[hidden email]>: >>> If you haven't done this already, you should look up Actalk, which was >>> a version of Smalltalk that let you have many classes with the same >>> metaclass. >>> >>> http://map.squeak.org/package/19ae332d-1111-4131-8b56-1fd7e9d2b35f >>> >>> I never used Actalk, I just read the papers. It was an interesting >>> and worthwhile experiment, but I wasn't convinced that the change was >>> worthwhile. But perhaps we just need to figure out more to do with >>> it. >>> >>> What you are saying is a little different. You are just complaining >>> about hardcoding the assumption that each clas has a unique metaclass. >>> All you are really asking is to get rid of the "thisClass" variable. >>> I don't see any harm in that. I bet that "new" is rarely called more >>> than once on any metaclass, and that one time is during the creation >>> of the class/metaclass pair. The bigger issue is that when you >>> evaluate and print the expression "Object class", what happens is that >>> it computes the metaclass and then asks the metaclass to print itself, >>> which it does by fetching the name of its sole instance and appending >>> " class" to it. In other words, a metaclass does not have a name, but >>> derives its name from the name of its sole instance. But this doesn't >>> have to be fast, either. You could call allInstances to find out the >>> instance and get its name. My guess is that it would hardly be >>> noticeable. >>> >> >> My own guess is that there would be a noticeable down speed in code >> management tools (Monticello & al). >> >> Nicolas >> > > Posted too fast... > Beside, if it has several instances, then why insisting on giving a > name related to a specific instance ? > i second that. If problem is only about identifying metaclass by name, then why not just add a 'name' ivar to metaclass, and let metaclass to print itself with whatever name it desire? > Nicolas > -- Best regards, Igor Stasenko AKA sig. |
In reply to this post by Nicolas Cellier
On Tue, Dec 8, 2009 at 8:02 AM, Nicolas Cellier
<[hidden email]> wrote: > Beside, if it has several instances, then why insisting on giving a > name related to a specific instance ? That is the way it works now. If you want to give several instances to a metaclass, you will need to come up with some other way of naming metaclasses. But just getting rid of "thisClass" would not require adding a "name" variable to MetaClass. -Ralph |
In reply to this post by Igor Stasenko
Igor Stasenko wrote:
> For people who think that we should not revise the class/metaclass > coupling in Squeak, > just ignore this topic and consider it as a rant :) > > For those, who interested why i think its not a perfect from > object-oriented point of view, continue reading. It may help your thinking about the problem when you realize that the core coupling between object and class, is as simple as: Class new class == Class. I.e., if you can implement the #class method you could do something like: FooClass>>class ^FooFactory FooFactory>>new ^FooClass new This will work perfectly fine in terms of the "everyday use" of classes. I had thought about utilizing this to create "safe classes" that is classes that separate the factory / utility aspect from the vtable aspect (FooFactory can expose instance creation and utility methods without exposing the implemntation / compilation aspect provided by FooClass class'). Cheers, - Andreas |
2009/12/8 Andreas Raab <[hidden email]>:
> Igor Stasenko wrote: >> >> For people who think that we should not revise the class/metaclass >> coupling in Squeak, >> just ignore this topic and consider it as a rant :) >> >> For those, who interested why i think its not a perfect from >> object-oriented point of view, continue reading. > > It may help your thinking about the problem when you realize that the core > coupling between object and class, is as simple as: > > Class new class == Class. > erm.. at least 2 messages between 'Class' to the left and 'Class' to the right could do something completely different, so as result you will get false (or something else, if #== overridden itself). Of course i leaving an aggressive optimization of #class and #== aside. As any expression you writing in smalltalk, you can't tell what will be result before evaluating it. > I.e., if you can implement the #class method you could do something like: > > FooClass>>class > ^FooFactory > > FooFactory>>new > ^FooClass new > > This will work perfectly fine in terms of the "everyday use" of classes. I > had thought about utilizing this to create "safe classes" that is classes > that separate the factory / utility aspect from the vtable aspect > (FooFactory can expose instance creation and utility methods without > exposing the implemntation / compilation aspect provided by FooClass > class'). > There are few aspects, which is hardcoded in VM in respect, what objects could serve as an object factory (by using #basicNew, or #basicNew: primitives). One could easily create own factory objects, as soon as VM requirements met ('superclass methodDict format' slots). "If it walks like a duck and quacks like a duck, it must be a duck" Btw, by reading an essay (a link provided by Eliot few days ago) where discussed a difference between ADT (abstract data types) and objects, there were very good observation about objects, which is a good complement to duck typing: Two objects considered equal, if they simulating each one's behavior. > Cheers, > - Andreas -- Best regards, Igor Stasenko AKA sig. |
Here are simple example, of what powers lies beneath, yet untamed.
now, try this: | factory instance | factory := CustomObjectFactory new superclass: Color. instance := factory createInstance. { instance class. instance class class } prints -> an Array(CustomObjectFactory(Color) CustomObjectFactory) btw, there are something baad with Point class. Seems like there are interference with compact classes in VM. | factory instance | factory := CustomObjectFactory new superclass: Point. instance := factory createInstance. instance class == factory prints ->> false Now lets go back to original question. The metaclass of instance of CustomObjectFactory(Color) appears to be a CustomObjectFactory.. but i can create as many instances of CustomObjectFactory class as i want.. Or should i add 'thisClass' ivar to CustomObjectFactory? ;) -- Best regards, Igor Stasenko AKA sig. CustomObjectFactory.st (2K) Download Attachment |
In reply to this post by Igor Stasenko
On Wed, Dec 9, 2009 at 12:49 AM, Igor Stasenko <[hidden email]> wrote:
> For people who think that we should not revise the class/metaclass > coupling in Squeak, > just ignore this topic and consider it as a rant :) > > For those, who interested why i think its not a perfect from > object-oriented point of view, continue reading. > > Ok. Lets start from basics. > > A classes, in smalltalk is a first class objects, which one of its > strong sides, comparing to other languages. > Since each object has a class, we also need an object which reflecting > the class itself, and hence the metaclass. > > But then, each class could have as many instances as it likes to, isnt? > But here the contradiction, which drives me nuts, when i looking at > Metaclass definition - 'thisClass' ivar. > > This implies that any metaclass could have only a single instance - class. > > Metaclass>>new > "The receiver can only have one instance. Create it or complain that > one already exists." > > thisClass class ~~ self > ifTrue: [^thisClass := self basicNew] > ifFalse: [self error: 'A Metaclass should only have one instance!'] > > but hey.. > what you suppose to do with things like: > > SomeClass clone > > ? That should probably fail. Instead, use >>copy, which (I suspect) makes a new instance of Metaclass as well. > I am trying to understand, why do we need this inconsistency by > enforcing such a rigid rule. > > Like, how often you may need to determine a 'sole' instance of the > class, or all instances? > And why it needs to be so fast by keeping a direct reference to it? > > System browser could live well without it. > Altering the metaclass definition? Well, iterate over all instances > indiscriminately - using same mechanism as usual class doing for own > instances. > So, it is strange to me, why do we need such tight coupling.. > > Is anyone having insights about it? I'm interested in this because I'll be refactoring Class and Metaclass soon (next year) for SecureSqueak. I've already got my own Class/Metaclass hierarchies with no connections to the SystemDictionary, which allows me to experiment without breaking things. The only requirement for a class by the VM is that instance variable 1 is another valid class (the superclass), instance variable 2 is a valid method dictionary and instance variable 3 is a special "format" integer. Otherwise you can add whatever you want; every other variable is optional. You can make your own classes which have no name, environment, pools and so forth - you'd just break the tools that inspect them. As for the tight coupling between class and metaclass, I guess it is pragmatic. There's no real reason to separate them. If you want a class with different instance-side methods but exactly the same class-side methods as another class, then you'd use inheritance. Because of the tight coupling, the instance variables in a Class or Metaclass instance could be in either; it makes no difference. Gulik. -- http://gulik.pbwiki.com/ |
2009/12/9 Michael van der Gulik <[hidden email]>:
> On Wed, Dec 9, 2009 at 12:49 AM, Igor Stasenko <[hidden email]> wrote: >> For people who think that we should not revise the class/metaclass >> coupling in Squeak, >> just ignore this topic and consider it as a rant :) >> >> For those, who interested why i think its not a perfect from >> object-oriented point of view, continue reading. >> >> Ok. Lets start from basics. >> >> A classes, in smalltalk is a first class objects, which one of its >> strong sides, comparing to other languages. >> Since each object has a class, we also need an object which reflecting >> the class itself, and hence the metaclass. >> >> But then, each class could have as many instances as it likes to, isnt? >> But here the contradiction, which drives me nuts, when i looking at >> Metaclass definition - 'thisClass' ivar. >> >> This implies that any metaclass could have only a single instance - class. >> >> Metaclass>>new >> "The receiver can only have one instance. Create it or complain that >> one already exists." >> >> thisClass class ~~ self >> ifTrue: [^thisClass := self basicNew] >> ifFalse: [self error: 'A Metaclass should only have one instance!'] >> >> but hey.. >> what you suppose to do with things like: >> >> SomeClass clone >> >> ? > > That should probably fail. Instead, use >>copy, which (I suspect) > makes a new instance of Metaclass as well. > >> I am trying to understand, why do we need this inconsistency by >> enforcing such a rigid rule. >> >> Like, how often you may need to determine a 'sole' instance of the >> class, or all instances? >> And why it needs to be so fast by keeping a direct reference to it? >> >> System browser could live well without it. >> Altering the metaclass definition? Well, iterate over all instances >> indiscriminately - using same mechanism as usual class doing for own >> instances. >> So, it is strange to me, why do we need such tight coupling.. >> >> Is anyone having insights about it? > > I'm interested in this because I'll be refactoring Class and Metaclass > soon (next year) for SecureSqueak. I've already got my own > Class/Metaclass hierarchies with no connections to the > SystemDictionary, which allows me to experiment without breaking > things. > something we should learn from :) Universe has no central point. Every point in Universe is its center. > The only requirement for a class by the VM is that instance variable 1 > is another valid class (the superclass), instance variable 2 is a > valid method dictionary and instance variable 3 is a special "format" > integer. Otherwise you can add whatever you want; every other variable > is optional. You can make your own classes which have no name, > environment, pools and so forth - you'd just break the tools that > inspect them. > Yes. And i'm always thinking towards making things less heavyweight, and keep only required minimal in class/behavior protocols that tools should know about, instead of thousands and thousands of methods implying tight coupling. > As for the tight coupling between class and metaclass, I guess it is > pragmatic. There's no real reason to separate them. If you want a > class with different instance-side methods but exactly the same > class-side methods as another class, then you'd use inheritance. A single class denotes a family of objects, which can be instantiated and have same behavior. Inheritance creates a different family of objects by specialization. The main problem with inheritance is that it doesn't solves any problems, it only inheriting them. Imagine a locomotive with bunch of wagons tied to id. The more wagons you adding, the slower it become, no matter how powerful it was initially. What you proposing is adding another wagon to the train and expect that it will run faster. > Because of the tight coupling, the instance variables in a Class or > Metaclass instance could be in either; it makes no difference. > Not sure i understood, what instance variables you talking about. Any instance of class keeps reference back to a class through implicit class slot in object header. But class doesn't sees all of its instances directly, because its impractical. Still, there is a protocol that supports an idea of having a way to 'see' all its instances (allInstancesDo:). But to my thinking, this is an over-engineered stuff. Such kind of reflection useful purely for mutating instances (after modifying the class definition), but its too slow and fragile to be used for any real-time tasks, since it implies a linear scan of all objects in object memory. But new objects could be created at any moment, a process which scans the heap can be interrupted.. there are too much issues preventing this feature to work fine. Unless you register every created instance in some sort of collection and keep it in class's own ivar :) Conserning instances mutation: You, as a designer of secure-squeak, should know well about problematics of class modification (especially mutation of its instances). It should be prohibited. Instead, one should create a modified copy, but never replace the old class by modified one and never attempt to mutate exising instances.. otherwise you will be unable to contaminate the numerous security problems. > Gulik. > > -- > http://gulik.pbwiki.com/ > -- Best regards, Igor Stasenko AKA sig. |
Free forum by Nabble | Edit this page |