[Pharo-project] Quasi-stateful traits?
To test out the possibilities of using traits for refactoring, I had a go at rationalising OmniBrowser/OmniBrowser2. This showed up that it appears to be possible to use the current traits implementation in a 'quasi-stateful' manner. that is, you can directly address the variables of a trait's 'hosting' class. This is rather contrary to my previous understanding of stateless traits. Is this normal behaviour? I've written up the details here. http://neat-sheet.com/development-blog.html/ ...Stan -- View this message in context: http://n4.nabble.com/Quasi-stateful-traits-tp1571120p1571120.html Sent from the Pharo Smalltalk mailing list archive at Nabble.com.
stan as one of the trait "guy" we should consider that - probably what we got can be improved for example I was discussing about the implementation in javascript and tom is proposing to have a a shallow rename of methods + adding a requirement instead of an alias (this way you can limit the interface explosion) - I did not like the stateful traits even if this is my idea. what we tried to do what do make sure that we do not have to recompile the code in each user. Now since methods are not shared (I'm sad about that) between trait user then we could recompile the methods for each user and users could have different states and state layout. - for state the question in initialize: how do we initialize trait state in the composite in an elegant way in ambianttalk we get T1>>initialize T2>>initialize C T1 initialize -> T1init T2 initialize -> T2init and initialize self T1init. self T2init - for Plug like delegatee we are working with people from KUL on understanding a kind of subobject trait based approach. We will send information when the paper is published. But you can read the ecoop paper of marko van dooren - Did you check the solution proposed in VW to have state in traits? I do not remember it (shame on my weak memory)
To test out the possibilities of using traits for refactoring, I had a go at rationalising OmniBrowser/OmniBrowser2.
Good! I like the idea to have traits shared between browser.
This showed up that it appears to be possible to use the current traits implementation in a 'quasi-stateful' manner. that is, you can directly address the variables of a trait's 'hosting' class. This is rather contrary to my previous understanding of stateless traits. Is this normal behaviour?
I've written up the details here.
http://neat-sheet.com/development-blog.html/
...Stan -- View this message in context: http://n4.nabble.com/Quasi-stateful-traits-tp1571120p1571120.html Sent from the Pharo Smalltalk mailing list archive at Nabble.com.
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
To test out the possibilities of using traits for refactoring, I had a go at rationalising OmniBrowser/OmniBrowser2.
Good! I like the idea to have traits shared between browser.
What is the benefit for the maintainers of the two browser? To me this doesn't make any sense: the Traits themselves don't have any meaning, they are just there to share code that randomly matches in both implementations. I imagine that changing a trait for one browser almost certainly breaks something in the other browser? Who ensures that the trait use is kept in sync between the two implementations? How can I avoid to accidentally leak code from one browser into the other one? What happens if one of the browsers reactors its class hierarchy? To me this all looks like a lot more work, more things to maintain and think about. The only reasonable solution of reuse for O2 would be to use OB as it is intended to be used. The fork only exists because O2 applies crosscutting changes throughout the complete OB meta-model, the view and the specific model of the standard browser. Numerous other browsers have successfully been built and they show nearly 100% code reuse: the refactoring browser, the debugger, the inspector, the workspace, the transcript, all the GemStone tools, the Monticello 2 browsers, the Seaside browsers, Pier browser, ... Lukas -- Lukas Renggli http://www.lukas-renggli.ch
Lukas Renggli wrote:
To test out the possibilities of using traits for refactoring, I had a go at rationalising OmniBrowser/OmniBrowser2.
Good! I like the idea to have traits shared between browser.
What is the benefit for the maintainers of the two browser?
I should imagine none ;) I wouldn't advocate this approach for two projects that are going to remain separate. While there would be a small saving in double handling bugs in the common methods, as in http://code.google.com/p/pharo/issues/detail?id=1887&can=1&q=copy&sort=-id&c... Issue 1887 it wouldn't outweigh the hassle.
To me this doesn't make any sense: the Traits themselves don't have any meaning, they are just there to share code that randomly matches in both implementations. I imagine that changing a trait for one browser almost certainly breaks something in the other browser? Who ensures that the trait use is kept in sync between the two implementations? How can I avoid to accidentally leak code from one browser into the other one? What happens if one of the browsers reactors its class hierarchy?
To me this all looks like a lot more work, more things to maintain and think about.
Again, I wouldn't advocate this for two actively, separately maintained, packages. But in the hypothetical where you did try this:
changing a trait for one browser almost certainly breaks something in the other browser
I think if you wanted the methods no longer to be the same, you would implement the change back in your version of the class. The other user would see no change.
Who ensures that the trait use is kept in sync between the two implementations? How can I avoid to accidentally leak code from one browser into the other one? The person who made any mod would have the choice of doing so unilaterally, in the local class, or of negotiating a common change. You do get prompted to ask whether you want to change the trait or make the change locally, but you could accidentally change the trait by clicking the wrong option.
What happens if one of the browsers reactors its class hierarchy?
Then clearly all bets would be off, because they are no longer common in that sense. The refactoring version would repatriate its traits into methods and go from there. I could see the trait approach being useful in the following circumstances: The two versions decide to get together and heal the fork. Taking the functionality apart into traits helps to identify what is different, what actually needs to be different, and how it can be moved to non-interfering places. or Before the fork takes place, the two versions decide that forking is necessary, but they wish to retain as much commonality as possible. Cheers, ...Stan -- View this message in context: http://n4.nabble.com/Quasi-stateful-traits-tp1571120p1571540.html Sent from the Pharo Smalltalk mailing list archive at Nabble.com.
Stéphane Ducasse wrote:
stan
as one of the trait "guy" we should consider that - probably what we got can be improved for example I was discussing about the implementation in javascript and tom is proposing to have a a shallow rename of methods + adding a requirement instead of an alias (this way you can limit the interface explosion)
- I did not like the stateful traits even if this is my idea. what we tried to do what do make sure that we do not have to recompile the code in each user. Now since methods are not shared (I'm sad about that) between trait user then we could recompile the methods for each user and users could have different states and state layout.
- for state the question in initialize: how do we initialize trait state in the composite in an elegant way in ambianttalk we get T1>>initialize T2>>initialize C T1 initialize -> T1init T2 initialize -> T2init and initialize self T1init. self T2init
- for Plug like delegatee we are working with people from KUL on understanding a kind of subobject trait based approach. We will send information when the paper is published. But you can read the ecoop paper of marko van dooren
- Did you check the solution proposed in VW to have state in traits? I do not remember it (shame on my weak memory)
No, I didn't get to that one.
To test out the possibilities of using traits for refactoring, I had a go at rationalising OmniBrowser/OmniBrowser2.
Good! I like the idea to have traits shared between browser.
It's possible to try out the 'semi-healed' version. In a new image: Gofer new squeaksource: 'MetacelloRepository'; package:'ConfigurationOfHealer'; load. ((Smalltalk at: #ConfigurationOfHealedOmniBrowser) project version: '0.6-baseline') load . Not recommended on your production system.
This showed up that it appears to be possible to use the current traits implementation in a 'quasi-stateful' manner. that is, you can directly address the variables of a trait's 'hosting' class. This is rather contrary to my previous understanding of stateless traits. Is this normal behaviour?
I've written up the details here.
http://neat-sheet.com/development-blog.html/
...Stan
-- View this message in context: http://n4.nabble.com/Quasi-stateful-traits-tp1571120p1571472.html Sent from the Pharo Smalltalk mailing list archive at Nabble.com.
One of the ways of introducing a stateful traits is changing the VM object format. There is a bits in object's header reserved for identity hash. Instead of putting the identify hash value there, we could use it to indicate if given object has additional arbitrary slots following the object contents: <header> <ivar1> ... <ivarN> <variableVar1> ... <variableVarM> <key1><value1> <key2><value2> ... <keyK><valueK> so, these keyN->valueN forming a dictionary of key/value pairs, which can be accessed using new primitives #slotAt: and #sloatAt:put: slot allocaiton can be expressed as: newObject := object copyWithSlot: key value: value. object becomeForward: newObject. (except that this is done by VM primitively). Once slots is allocated, object size is not grows anymore (so there are no overhead) and as bonus, you getting a way to attach any additional state to virtually any objects (except smallints) , for any purposes. Identity hash is become slower, but only at first hashing attempt. (slotAt: #identityHash put: value) But as benefit, we could use any object (or just 31 bit small integer) for hash values, which will increase the hashing quality considerably. So, it is a question, what will be faster, especially for large dictionaries. Obviously, then traits free to use this to keep own state, without any extra demands from classes where it installed: foo ^ self slotAt: #foo foo: value self slotAt: #foo put: value Also, I think that with such extension, we might expect a considerable speed boost for Magma OODB, which can use additional slot for marking objects by own ids, as well as for marking object dirty, instead of maintaining a huge and ineffective IdentityDictionaries to track the objects state. -- Best regards, Igor Stasenko AKA sig.
Igor Stasenko wrote:
One of the ways of introducing a stateful traits is changing the VM object format.
Sounds like it could be very powerful. As it happens, in the fork healing example, it's the very statelessness of the traits that make it work so simply. By taking out the check for statefulness when the method is moved to a trait, the trait will quite happily address the several variables in its user classes. This then removes any need for accessors, helper classes for state, initialization, or other attempts to tame the beast. I wouldn't want to rely on it continuing to work in all conditions, but as a step in a refactoring it seems very handy. ..Stan -- View this message in context: http://n4.nabble.com/Quasi-stateful-traits-tp1571120p1571553.html Sent from the Pharo Smalltalk mailing list archive at Nabble.com.
On a second thought, i think this is not really necessary. Traits can be reformulated to be purely a method source holders, not holders of compiled methods. (And btw, this is actually true, due to the latest changes in traits, because of super sends issues and #methodClass), we only need to push it a little further and get rid of useless limitations. The point is, that all trait methods should _always_ be compiled in the scope of the class to which it applied. Because, for any variable name, which not declared explicitly in the method's scope, we can't tell anything about it, until we apply this method to the real class (See the Class>>bindingOf: ) This means that, even if you having the trait method: foo ^ Array new: 10 the binding of 'Array' variable may be different, depending on class where its installed. To check it, you can try following at home: Object subclass: #ZZZZ instanceVariableNames: '' classVariableNames: 'DD' poolDictionaries: '' category: 'ZZZZ' "add new pool variable" ZZZZ classPool at: #Array put: 10. "now add the method" array ^ Array and now evaluate the following: ZZZZ new array ------------- But what makes array ^ Array method any better than array ^ array := 10. in this regard? Nothing. So, why not drop the limitation, and instead of punishing developer for use undeclared vars in trait methods, punish him for use of undeclared variables, when he tries to apply the trait to concrete class, where all such var names should obtain meaning? Then, ultimately, what is the point in storing compiling methods in Trait (not for classes, where it applied). We could just check the syntax, but should not produce any CompiledMethod instances at all. What other problems i don't see here? On 27 February 2010 02:10, Stan Shepherd <stan.shepherd414@gmail.com> wrote:
Igor Stasenko wrote:
One of the ways of introducing a stateful traits is changing the VM object format.
Sounds like it could be very powerful.
As it happens, in the fork healing example, it's the very statelessness of the traits that make it work so simply. By taking out the  check for statefulness when the method is moved to a trait, the trait will quite happily address the several variables in its user classes. This then removes any need for accessors, helper classes for state, initialization, or other attempts to tame the beast.
I wouldn't want to rely on it continuing to work in all conditions, but as a step in a refactoring it seems very handy.
..Stan -- View this message in context: http://n4.nabble.com/Quasi-stateful-traits-tp1571120p1571553.html Sent from the Pharo Smalltalk mailing list archive at Nabble.com.
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
-- Best regards, Igor Stasenko AKA sig.
On Feb 27, 2010, at 4:13 AM, Igor Stasenko wrote:
On a second thought, i think this is not really necessary.
Traits can be reformulated to be purely a method source holders, not holders of compiled methods. (And btw, this is actually true, due to the latest changes in traits, because of super sends issues and #methodClass), we only need to push it a little further and get rid of useless limitations.
The point is, that all trait methods should _always_ be compiled in the scope of the class to which it applied.
Yes this was implied in what I said but I did not want to say it explictly :)
Because, for any variable name, which not declared explicitly in the method's scope, we can't tell anything about it, until we apply this method to the real class (See the Class>>bindingOf: ) This means that, even if you having the trait method:
foo ^ Array new: 10
the binding of 'Array' variable may be different, depending on class where its installed. To check it, you can try following at home:
Object subclass: #ZZZZ instanceVariableNames: '' classVariableNames: 'DD' poolDictionaries: '' category: 'ZZZZ'
"add new pool variable" ZZZZ classPool at: #Array put: 10.
"now add the method" array ^ Array
and now evaluate the following: ZZZZ new array
------------- But what makes array ^ Array
method any better than
array ^ array := 10.
in this regard?
Nothing. So, why not drop the limitation, and instead of punishing developer for use undeclared vars in trait methods, punish him for use of undeclared variables, when he tries to apply the trait to concrete class, where all such var names should obtain meaning?
Then, ultimately, what is the point in storing compiling methods in Trait (not for classes, where it applied). We could just check the syntax, but should not produce any CompiledMethod instances at all.
What other problems i don't see here?
I do not see. I think that this is nice to do another iteration around traits.
On 27 February 2010 02:10, Stan Shepherd <stan.shepherd414@gmail.com> wrote:
Igor Stasenko wrote:
One of the ways of introducing a stateful traits is changing the VM object format.
Sounds like it could be very powerful.
As it happens, in the fork healing example, it's the very statelessness of the traits that make it work so simply. By taking out the check for statefulness when the method is moved to a trait, the trait will quite happily address the several variables in its user classes. This then removes any need for accessors, helper classes for state, initialization, or other attempts to tame the beast.
I wouldn't want to rely on it continuing to work in all conditions, but as a step in a refactoring it seems very handy.
..Stan -- View this message in context: http://n4.nabble.com/Quasi-stateful-traits-tp1571120p1571553.html Sent from the Pharo Smalltalk mailing list archive at Nabble.com.
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
-- Best regards, Igor Stasenko AKA sig.
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Igor Stasenko wrote:
Traits can be reformulated to be purely a method source holders, not holders of compiled methods. (And btw, this is actually true, due to the latest changes in traits, because of super sends issues and #methodClass)
OK, so that explains why they can currently be used as if they are stateful.
, we only need to push it a little further and get rid of useless limitations.
The point is, that all trait methods should _always_ be compiled in the scope of the class to which it applied. Because, for any variable name, which not declared explicitly in the method's scope, we can't tell anything about it, until we apply this method to the real class (See the Class>>bindingOf: ) This means that, even if you having the trait method:
foo ^ Array new: 10
the binding of 'Array' variable may be different, depending on class where its installed. To check it, you can try following at home:
Object subclass: #ZZZZ instanceVariableNames: '' classVariableNames: 'DD' poolDictionaries: '' category: 'ZZZZ'
"add new pool variable" ZZZZ classPool at: #Array put: 10.
"now add the method" array ^ Array
and now evaluate the following: ZZZZ new array
------------- But what makes array ^ Array
method any better than
array ^ array := 10.
in this regard?
Nothing. So, why not drop the limitation, and instead of punishing developer for use undeclared vars in trait methods, punish him for use of undeclared variables, when he tries to apply the trait to concrete class, where all such var names should obtain meaning?
Then, ultimately, what is the point in storing compiling methods in Trait (not for classes, where it applied). We could just check the syntax, but should not produce any CompiledMethod instances at all.
What other problems i don't see here?
The merged OB/O2 case still passes a full system test, so I didn't run into any show-stoppers. Traits that work this way, supported by the tools, would appear to make them applicable to a lot more cases. ...Stan
On 27 February 2010 02:10, Stan Shepherd <stan.shepherd414@gmail.com> wrote:
Igor Stasenko wrote:
One of the ways of introducing a stateful traits is changing the VM object format.
Sounds like it could be very powerful.
As it happens, in the fork healing example, it's the very statelessness of the traits that make it work so simply. By taking out the  check for statefulness when the method is moved to a trait, the trait will quite happily address the several variables in its user classes. This then removes any need for accessors, helper classes for state, initialization, or other attempts to tame the beast.
I wouldn't want to rely on it continuing to work in all conditions, but as a step in a refactoring it seems very handy.
..Stan -- View this message in context: http://n4.nabble.com/Quasi-stateful-traits-tp1571120p1571553.html Sent from the Pharo Smalltalk mailing list archive at Nabble.com.
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
-- Best regards, Igor Stasenko AKA sig.
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
-- View this message in context: http://n4.nabble.com/Quasi-stateful-traits-tp1571120p1571899.html Sent from the Pharo Smalltalk mailing list archive at Nabble.com.
orthogonally to traits I sometimes would like python like hash based (but class and not object) semantics ie Object dictionaryVariable: #MyClass Igor now one of the problem is see with the possible to add and access slot everywhere is illustrated by morphic code when a method add a property extension to a morph, another tests for its value and the third one remove it. You get code that is really difficult to understand.
<key1><value1> <key2><value2>
On Feb 27, 2010, at 12:39 AM, Igor Stasenko wrote:
One of the ways of introducing a stateful traits is changing the VM object format. There is a bits in object's header reserved for identity hash. Instead of putting the identify hash value there, we could use it to indicate if given object has additional arbitrary slots following the object contents:
<header> <ivar1> ... <ivarN> <variableVar1> ... <variableVarM> <key1><value1> <key2><value2> ... <keyK><valueK>
so, these keyN->valueN forming a dictionary of key/value pairs, which can be accessed using new primitives #slotAt: and #sloatAt:put:
slot allocaiton can be expressed as:
newObject := object copyWithSlot: key value: value. object becomeForward: newObject.
(except that this is done by VM primitively).
Once slots is allocated, object size is not grows anymore (so there are no overhead) and as bonus, you getting a way to attach any additional state to virtually any objects (except smallints) , for any purposes. Identity hash is become slower, but only at first hashing attempt. (slotAt: #identityHash put: value) But as benefit, we could use any object (or just 31 bit small integer) for hash values, which will increase the hashing quality considerably. So, it is a question, what will be faster, especially for large dictionaries.
Obviously, then traits free to use this to keep own state, without any extra demands from classes where it installed:
foo ^ self slotAt: #foo foo: value self slotAt: #foo put: value
Also, I think that with such extension, we might expect a considerable speed boost for Magma OODB, which can use additional slot for marking objects by own ids, as well as for marking object dirty, instead of maintaining a huge and ineffective IdentityDictionaries to track the objects state.
-- Best regards, Igor Stasenko AKA sig.
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
On 27 February 2010 10:11, Stéphane Ducasse <stephane.ducasse@inria.fr> wrote:
orthogonally to traits I sometimes would like python like hash based (but class and not object) semantics ie
Object dictionaryVariable: #MyClass
Igor now one of the problem is see with the possible to add and access slot everywhere is illustrated by morphic code when a method add a property extension to a morph, another tests for its value and the third one remove it. You get code that is really difficult to understand.
<key1><value1> <key2><value2>
This is an object memmory layout - a pair of two oops(object pointers) one following other - key and value.
On Feb 27, 2010, at 12:39 AM, Igor Stasenko wrote:
One of the ways of introducing a stateful traits is changing the VM object format. There is a bits in object's header reserved for identity hash. Instead of putting the identify hash value there, we could use it to indicate if given object has additional arbitrary slots following the object contents:
<header> <ivar1> ... <ivarN> <variableVar1> ... <variableVarM> <key1><value1> <key2><value2> ... <keyK><valueK>
so, these keyN->valueN forming a dictionary of key/value pairs, which can be accessed using new primitives #slotAt: and #sloatAt:put:
slot allocaiton can be expressed as:
newObject := object copyWithSlot: key value: value. object becomeForward: newObject.
(except that this is done by VM primitively).
Once slots is allocated, object size is not grows anymore (so there are no overhead) and as bonus, you getting a way to attach any additional state to virtually any objects (except smallints) , for any purposes. Identity hash is become slower, but only at first hashing attempt. (slotAt: #identityHash put: value) But as benefit, we could use any object (or just 31 bit small integer) for hash values, which will increase the hashing quality considerably. So, it is a question, what will be faster, especially for large dictionaries.
Obviously, then traits free to use this to keep own state, without any extra demands from classes where it installed:
foo  ^ self slotAt: #foo foo: value  self slotAt: #foo put: value
Also, I think that with such extension, we might expect a considerable speed boost for Magma OODB, which can use additional slot for marking objects by own ids, as well as for marking object dirty, instead of maintaining a huge and ineffective IdentityDictionaries to track the objects state.
-- Best regards, Igor Stasenko AKA sig.
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
-- Best regards, Igor Stasenko AKA sig.
On Feb 27, 2010, at 5:12 PM, Igor Stasenko wrote:
On 27 February 2010 10:11, Stéphane Ducasse <stephane.ducasse@inria.fr> wrote:
orthogonally to traits I sometimes would like python like hash based (but class and not object) semantics ie
Object dictionaryVariable: #MyClass
Igor now one of the problem is see with the possible to add and access slot everywhere is illustrated by morphic code when a method add a property extension to a morph, another tests for its value and the third one remove it. You get code that is really difficult to understand.
<key1><value1> <key2><value2>
This is an object memmory layout - a pair of two oops(object pointers) one following other - key and value.
yes I got it. My point is still valid
Igor now one of the problem is see with the possible to add and access slot everywhere is illustrated by morphic code when a method add a property extension to a morph, another tests for its value and the third one remove it. You get code that is really difficult to understand.
On Feb 27, 2010, at 12:39 AM, Igor Stasenko wrote:
One of the ways of introducing a stateful traits is changing the VM object format. There is a bits in object's header reserved for identity hash. Instead of putting the identify hash value there, we could use it to indicate if given object has additional arbitrary slots following the object contents:
<header> <ivar1> ... <ivarN> <variableVar1> ... <variableVarM> <key1><value1> <key2><value2> ... <keyK><valueK>
so, these keyN->valueN forming a dictionary of key/value pairs, which can be accessed using new primitives #slotAt: and #sloatAt:put:
slot allocaiton can be expressed as:
newObject := object copyWithSlot: key value: value. object becomeForward: newObject.
(except that this is done by VM primitively).
Once slots is allocated, object size is not grows anymore (so there are no overhead) and as bonus, you getting a way to attach any additional state to virtually any objects (except smallints) , for any purposes. Identity hash is become slower, but only at first hashing attempt. (slotAt: #identityHash put: value) But as benefit, we could use any object (or just 31 bit small integer) for hash values, which will increase the hashing quality considerably. So, it is a question, what will be faster, especially for large dictionaries.
Obviously, then traits free to use this to keep own state, without any extra demands from classes where it installed:
foo ^ self slotAt: #foo foo: value self slotAt: #foo put: value
Also, I think that with such extension, we might expect a considerable speed boost for Magma OODB, which can use additional slot for marking objects by own ids, as well as for marking object dirty, instead of maintaining a huge and ineffective IdentityDictionaries to track the objects state.
-- Best regards, Igor Stasenko AKA sig.
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
-- Best regards, Igor Stasenko AKA sig.
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
On 27 February 2010 18:44, Stéphane Ducasse <stephane.ducasse@inria.fr> wrote:
On Feb 27, 2010, at 5:12 PM, Igor Stasenko wrote:
On 27 February 2010 10:11, Stéphane Ducasse <stephane.ducasse@inria.fr> wrote:
orthogonally to traits I sometimes would like python like hash based (but class and not object) semantics ie
Object dictionaryVariable: #MyClass
Igor now one of the problem is see with the possible to add and access slot everywhere is illustrated by morphic code when a method add a property extension to a morph, another tests for its value and the third one remove it. You get code that is really difficult to understand.
<key1><value1> <key2><value2>
This is an object memmory layout - a pair of two oops(object pointers) one following other - Â key and value.
yes I got it.
My point is still valid
Igor now one of the problem is see with the possible to add and access slot everywhere is illustrated by morphic code when a method add a property extension to a morph, another tests for its value and the third one remove it. You get code that is really difficult to understand.
You mean that morphs could add arbitrary slots to its instances? Why difficult? This extension is to match the object format of Self and JavaScript.
On Feb 27, 2010, at 12:39 AM, Igor Stasenko wrote:
One of the ways of introducing a stateful traits is changing the VM object format. There is a bits in object's header reserved for identity hash. Instead of putting the identify hash value there, we could use it to indicate if given object has additional arbitrary slots following the object contents:
<header> <ivar1> ... <ivarN> <variableVar1> ... <variableVarM> <key1><value1> <key2><value2> ... <keyK><valueK>
so, these keyN->valueN forming a dictionary of key/value pairs, which can be accessed using new primitives #slotAt: and #sloatAt:put:
slot allocaiton can be expressed as:
newObject := object copyWithSlot: key value: value. object becomeForward: newObject.
(except that this is done by VM primitively).
Once slots is allocated, object size is not grows anymore (so there are no overhead) and as bonus, you getting a way to attach any additional state to virtually any objects (except smallints) , for any purposes. Identity hash is become slower, but only at first hashing attempt. (slotAt: #identityHash put: value) But as benefit, we could use any object (or just 31 bit small integer) for hash values, which will increase the hashing quality considerably. So, it is a question, what will be faster, especially for large dictionaries.
Obviously, then traits free to use this to keep own state, without any extra demands from classes where it installed:
foo  ^ self slotAt: #foo foo: value  self slotAt: #foo put: value
Also, I think that with such extension, we might expect a considerable speed boost for Magma OODB, which can use additional slot for marking objects by own ids, as well as for marking object dirty, instead of maintaining a huge and ineffective IdentityDictionaries to track the objects state.
-- Best regards, Igor Stasenko AKA sig.
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
-- Best regards, Igor Stasenko AKA sig.
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
-- Best regards, Igor Stasenko AKA sig.
My point is still valid
Igor now one of the problem is see with the possible to add and access slot everywhere is illustrated by morphic code when a method add a property extension to a morph, another tests for its value and the third one remove it. You get code that is really difficult to understand.
You mean that morphs could add arbitrary slots to its instances?
yes look at addProperty and friends
Why difficult?
Apparently you never tried to understand morphic code. Try in Squeak 3.9 not pharo because we removed a lot of problem already
This extension is to match the object format of Self and JavaScript.
Why do we need that? When do you need that? Why an instance should have a dictionary based access? How this is integrate with our tools? Why a good mop does not let you do that :) We will be working on that I asked but this is several years that I think that under specific circumstances it would make sense to have Object dictionaryVariableSubclass: but not just to look like self or javascript. Stef
On 27 February 2010 19:21, Stéphane Ducasse <stephane.ducasse@inria.fr> wrote:
My point is still valid
Igor now one of the problem is see with the possible to add and access slot everywhere is illustrated by morphic code when a method add a property extension to a morph, another tests for its value and the third one remove it. You get code that is really difficult to understand.
You mean that morphs could add arbitrary slots to its instances?
yes look at addProperty and friends
Why difficult?
Apparently you never tried to understand morphic code. Try in Squeak 3.9 not pharo because we removed a lot of problem already
I took a look. And addProperty & morphic-extensions is obviously not best pieces of code. The things is, that most of these properties usually set up only once on widget init and never touched during lifetime of morph. The possibility to remove the property from morph is cool, but used seldom. So, actually this means, that morphs could be built using a composition of dynamic and static properties - styles, and all you need is to pick a morph and apply style to it. And no need to support dozens of properties as an additional state on a per-morph basis.
This extension is to match the object format of Self and JavaScript.
Why do we need that? When do you need that? Why an instance should have a dictionary based access? How this is integrate with our tools?
Why a good mop does not let you do that :)
Maybe because its not good enough?
We will be working on that
I asked but this is several years that I think that under specific circumstances it would make sense to have
Object dictionaryVariableSubclass:
but not just to look like self or javascript.
Stef
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
-- Best regards, Igor Stasenko AKA sig.
participants (4)
-
Igor Stasenko -
Lukas Renggli -
Stan Shepherd -
Stéphane Ducasse