[Pharo-project] syntax highlighting for (stateful) traits (non-local methods)
Hi all, as you know I'm working on stateful traits using my new classbuilder etc... Now I noticed that methods are highlighted always inside of the context of the class that's active in the class browser. How can I change this? There is already a useful method around to figure out which object it belongs to: SomeClass traitOrClassOfSelector: #aMethod This actually will tell me which trait it comes from. So now I could apply syntax coloring in the context of the trait rather than the class. Since in my implementation state is all private to the trait / class, they should be able to access their own state but not see the state of the other class. This obviously also means that coloring should happen in the correct scope, rather than always in the scope of the class. At the moment the coloring doesn't really make sense ... but then it didn't really matter that much until now. Although if you try to access state in a method coming from a trait, while coding in your IDE you'll probably have the impression you can access your local instvars. I don't really know what the semantics are there... but it seems a bit broken :) cheers, Toon
Ok, found it out by myself. I just hooked into OB directly: OBMethodDefinition> shouldBeStyledBy: aPluggableShoutMorph aPluggableShoutMorph classOrMetaClass: (theClass traitOrClassOfSelector: self selector). ^ true cheers, Toon On 04/02/2011 09:10 PM, Toon Verwaest wrote:
Hi all,
as you know I'm working on stateful traits using my new classbuilder etc... Now I noticed that methods are highlighted always inside of the context of the class that's active in the class browser. How can I change this? There is already a useful method around to figure out which object it belongs to:
SomeClass traitOrClassOfSelector: #aMethod
This actually will tell me which trait it comes from. So now I could apply syntax coloring in the context of the trait rather than the class. Since in my implementation state is all private to the trait / class, they should be able to access their own state but not see the state of the other class. This obviously also means that coloring should happen in the correct scope, rather than always in the scope of the class.
At the moment the coloring doesn't really make sense ... but then it didn't really matter that much until now. Although if you try to access state in a method coming from a trait, while coding in your IDE you'll probably have the impression you can access your local instvars. I don't really know what the semantics are there... but it seems a bit broken :)
cheers, Toon
On Apr 2, 2011, at 9:10 PM, Toon Verwaest wrote:
Hi all,
as you know I'm working on stateful traits using my new classbuilder
no Are you?
etc... Now I noticed that methods are highlighted always inside of the context of the class that's active in the class browser. How can I change this? There is already a useful method around to figure out which object it belongs to:
SomeClass traitOrClassOfSelector: #aMethod
This actually will tell me which trait it comes from. So now I could apply syntax coloring in the context of the trait rather than the class. Since in my implementation state is all private to the trait / class, they should be able to access their own state but not see the state of the other class. This obviously also means that coloring should happen in the correct scope, rather than always in the scope of the class.
At the moment the coloring doesn't really make sense ... but then it didn't really matter that much until now. Although if you try to access state in a method coming from a trait, while coding in your IDE you'll probably have the impression you can access your local instvars. I don't really know what the semantics are there... but it seems a bit broken :)
cheers, Toon
Oh yes.. I am :) http://pinocchio.unibe.ch/~tverwaes/slots.tar.gz gives you an image with an example of a stateful trait open. The state is always private to the class / trait at the moment and it already seems to work pretty well. I modified the NewInspector slightly to show you the proper data (although this needs to be cleaned up, and state should be sorted per trait), and the OB to compile and syntax highlight in the right context. I didn't test more complex examples yet than what's open, but it's designed generically enough that I'm confident it does ... euhm ... ;) cheers, Toon On 04/03/2011 10:44 AM, Stéphane Ducasse wrote:
On Apr 2, 2011, at 9:10 PM, Toon Verwaest wrote:
Hi all,
as you know I'm working on stateful traits using my new classbuilder no Are you?
etc... Now I noticed that methods are highlighted always inside of the context of the class that's active in the class browser. How can I change this? There is already a useful method around to figure out which object it belongs to:
SomeClass traitOrClassOfSelector: #aMethod
This actually will tell me which trait it comes from. So now I could apply syntax coloring in the context of the trait rather than the class. Since in my implementation state is all private to the trait / class, they should be able to access their own state but not see the state of the other class. This obviously also means that coloring should happen in the correct scope, rather than always in the scope of the class.
At the moment the coloring doesn't really make sense ... but then it didn't really matter that much until now. Although if you try to access state in a method coming from a trait, while coding in your IDE you'll probably have the impression you can access your local instvars. I don't really know what the semantics are there... but it seems a bit broken :)
cheers, Toon
Oh yes.. I am :)
cool How are you dealing with the fact that the application of trait with state may change the layout of the class user and that you should recompile all the class method to deal with that. And if you have two traits having state you should do the same but for the traits themselves. So this means that the method in the traits cannot be reused (ok now we do not reuse them anymore sniff it was a nice model - reuse without cost of duplication). How your layout object helps you for that? This is why I want first class slot :) Stef
http://pinocchio.unibe.ch/~tverwaes/slots.tar.gz gives you an image with an example of a stateful trait open. The state is always private to the class / trait at the moment and it already seems to work pretty well. I modified the NewInspector slightly to show you the proper data (although this needs to be cleaned up, and state should be sorted per trait), and the OB to compile and syntax highlight in the right context.
I didn't test more complex examples yet than what's open, but it's designed generically enough that I'm confident it does ... euhm ... ;)
cheers, Toon
On 04/03/2011 10:44 AM, Stéphane Ducasse wrote:
On Apr 2, 2011, at 9:10 PM, Toon Verwaest wrote:
Hi all,
as you know I'm working on stateful traits using my new classbuilder no Are you?
etc... Now I noticed that methods are highlighted always inside of the context of the class that's active in the class browser. How can I change this? There is already a useful method around to figure out which object it belongs to:
SomeClass traitOrClassOfSelector: #aMethod
This actually will tell me which trait it comes from. So now I could apply syntax coloring in the context of the trait rather than the class. Since in my implementation state is all private to the trait / class, they should be able to access their own state but not see the state of the other class. This obviously also means that coloring should happen in the correct scope, rather than always in the scope of the class.
At the moment the coloring doesn't really make sense ... but then it didn't really matter that much until now. Although if you try to access state in a method coming from a trait, while coding in your IDE you'll probably have the impression you can access your local instvars. I don't really know what the semantics are there... but it seems a bit broken :)
cheers, Toon
How are you dealing with the fact that the application of trait with state may change the layout of the class user and that you should recompile all the class method to deal with that. And if you have two traits having state you should do the same but for the traits themselves. So this means that the method in the traits cannot be reused (ok now we do not reuse them anymore sniff it was a nice model - reuse without cost of duplication).
How your layout object helps you for that? This is why I want first class slot :)
Stef I don't think I fully understand what you are saying...
The model is like this at the moment: Every class has a layout attached to it. Layouts that have slots have LayoutScopes. For example, if you have Class A super: Object slots: #(a b c) Class B super: A slots: #(d e) Then you get Class A <-> PointerLayout -> LayoutClassScope #(a b c) -> LayoutClassScope #() -> LayoutEmptyScope Class B <-> PointerLayout -> LayoutClassScope #(d e) -> LayoutClassScope #(a b c) -> LayoutClassScope #() -> LayoutEmptyScope where LayoutClassScope #(a b c) is shared between the scope of B and the layout of A. The empty LayoutClassScope comes from Object and is shared as well. Now if you get a stateful trait, a stateful trait C with slots #(f) looks like this: StatefulTrait C <-> PointerLayout -> LayoutTraitScope #(f) -> LayoutEmptyScope If you were to install the trait C on B, it would become: Class B <-> PointerLayout -> LayoutClassScope #(d e) -> LayoutForkScope -> LayoutClassScope #(a b c) -> LayoutClassScope #() -> LayoutEmptyScope where the LayoutForkScope would have sidescopes: LayoutForkScope sideScopes: { LayoutTraitScope #(f) -> LayoutEmptyScope } Then the classbuilder will build classes by always following the public path. Sidescopes aren't public. When you compile methods on the trait, its scopes are public; but when they are installed, they aren't public since they are sidescopes. However, every method is compiled on the trait or class that provided the selector, so when you install the trait-related method, it will see the state related to the trait. And when the trait is installed, the sidescopes are actually copies of the original traitscope, so the actual fieldindices are updated in the LayoutTraitScope when it's installed. Then how methods get updated based on state changes is at the moment completely unrelated to the trait implementation, since methods are already updated in my class builder based on a MethodModificationModel that knows how the fields have changed. This will use the decompiler/bytecode modification/recompiler to update the methods in place. The only thing that I forgot to do until now is to actually modify all the classes that use a trait, every time the state of a trait changes... But that's straightforward. We just have to ask for the users of the stateful trait and reapply their class modification. That's all nicely modeled already. As for overlapping state from multiple stateful traits.... there is no overlapping state since all state is private to the trait! You can use 2 traits with same slot names. This is no problem at all since the state is only seen by that trait. And their methods are only compiled on that trait, so the methods will always know exactly which of the slots you are referring to. I hope this helps somehow :) Otherwise ... wait for the paper ;) cheers, Toon
Then the classbuilder will build classes by always following the public path. Sidescopes aren't public. When you compile methods on the trait, its scopes are public; but when they are installed, they aren't public since they are sidescopes. I obviously meant, the compiler will compile methods by following the public path.
I guess that what Stef meant is the following: One of the problems when sharing code among mixin and stateful-trait application is that the physical layout of instances varies between mixin applications. (Section 6.5 of http://bergel.eu/download/papers/Berg07e-StatefulTraits.pdf) We have T.y and C.x T has a method #getY, for which its bytecode returns the first slot (i.e., y). If C uses T, the #getY needs to be adapted to return the second slot right? Cheers, Alexandre On 3 Apr 2011, at 06:23, Toon Verwaest wrote:
How are you dealing with the fact that the application of trait with state may change the layout of the class user and that you should recompile all the class method to deal with that. And if you have two traits having state you should do the same but for the traits themselves. So this means that the method in the traits cannot be reused (ok now we do not reuse them anymore sniff it was a nice model - reuse without cost of duplication).
How your layout object helps you for that? This is why I want first class slot :)
Stef I don't think I fully understand what you are saying...
The model is like this at the moment:
Every class has a layout attached to it. Layouts that have slots have LayoutScopes. For example, if you have
Class A super: Object slots: #(a b c) Class B super: A slots: #(d e)
Then you get
Class A <-> PointerLayout -> LayoutClassScope #(a b c) -> LayoutClassScope #() -> LayoutEmptyScope Class B <-> PointerLayout -> LayoutClassScope #(d e) -> LayoutClassScope #(a b c) -> LayoutClassScope #() -> LayoutEmptyScope
where LayoutClassScope #(a b c) is shared between the scope of B and the layout of A. The empty LayoutClassScope comes from Object and is shared as well.
Now if you get a stateful trait, a stateful trait C with slots #(f) looks like this:
StatefulTrait C <-> PointerLayout -> LayoutTraitScope #(f) -> LayoutEmptyScope
If you were to install the trait C on B, it would become:
Class B <-> PointerLayout -> LayoutClassScope #(d e) -> LayoutForkScope -> LayoutClassScope #(a b c) -> LayoutClassScope #() -> LayoutEmptyScope
where the LayoutForkScope would have sidescopes: LayoutForkScope sideScopes: { LayoutTraitScope #(f) -> LayoutEmptyScope }
Then the classbuilder will build classes by always following the public path. Sidescopes aren't public. When you compile methods on the trait, its scopes are public; but when they are installed, they aren't public since they are sidescopes.
However, every method is compiled on the trait or class that provided the selector, so when you install the trait-related method, it will see the state related to the trait. And when the trait is installed, the sidescopes are actually copies of the original traitscope, so the actual fieldindices are updated in the LayoutTraitScope when it's installed.
Then how methods get updated based on state changes is at the moment completely unrelated to the trait implementation, since methods are already updated in my class builder based on a MethodModificationModel that knows how the fields have changed. This will use the decompiler/bytecode modification/recompiler to update the methods in place.
The only thing that I forgot to do until now is to actually modify all the classes that use a trait, every time the state of a trait changes... But that's straightforward. We just have to ask for the users of the stateful trait and reapply their class modification. That's all nicely modeled already.
As for overlapping state from multiple stateful traits.... there is no overlapping state since all state is private to the trait! You can use 2 traits with same slot names. This is no problem at all since the state is only seen by that trait. And their methods are only compiled on that trait, so the methods will always know exactly which of the slots you are referring to.
I hope this helps somehow :) Otherwise ... wait for the paper ;)
cheers, Toon
-- _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.
On 04/03/2011 02:29 PM, Alexandre Bergel wrote:
I guess that what Stef meant is the following: One of the problems when sharing code among mixin and stateful-trait application is that the physical layout of instances varies between mixin applications. (Section 6.5 of http://bergel.eu/download/papers/Berg07e-StatefulTraits.pdf)
We have T.y and C.x T has a method #getY, for which its bytecode returns the first slot (i.e., y). If C uses T, the #getY needs to be adapted to return the second slot right?
Cheers, Alexandre Indeed. And this is not different from changing a layout of a class having as impact that you have to update the methods. The default traits implementation already recompiles all methods anyway whenever it installs the trait. What I do is, I just let the trait compile itself on the subpart of the class that originally defined the trait. Since this subpart is a copy of the original trait (just like the default traits does), it also has a COPY of the original layout. In this copy, the indices of the slots are updated when they are mixed with the class that is going to use the trait. So it's being compiled in the scope of the installed version of the trait-layout. So that easily works.
cheers
On 3 Apr 2011, at 06:23, Toon Verwaest wrote:
How are you dealing with the fact that the application of trait with state may change the layout of the class user and that you should recompile all the class method to deal with that. And if you have two traits having state you should do the same but for the traits themselves. So this means that the method in the traits cannot be reused (ok now we do not reuse them anymore sniff it was a nice model - reuse without cost of duplication).
How your layout object helps you for that? This is why I want first class slot :)
Stef I don't think I fully understand what you are saying...
The model is like this at the moment:
Every class has a layout attached to it. Layouts that have slots have LayoutScopes. For example, if you have
Class A super: Object slots: #(a b c) Class B super: A slots: #(d e)
Then you get
Class A<-> PointerLayout -> LayoutClassScope #(a b c) -> LayoutClassScope #() -> LayoutEmptyScope Class B<-> PointerLayout -> LayoutClassScope #(d e) -> LayoutClassScope #(a b c) -> LayoutClassScope #() -> LayoutEmptyScope
where LayoutClassScope #(a b c) is shared between the scope of B and the layout of A. The empty LayoutClassScope comes from Object and is shared as well.
Now if you get a stateful trait, a stateful trait C with slots #(f) looks like this:
StatefulTrait C<-> PointerLayout -> LayoutTraitScope #(f) -> LayoutEmptyScope
If you were to install the trait C on B, it would become:
Class B<-> PointerLayout -> LayoutClassScope #(d e) -> LayoutForkScope -> LayoutClassScope #(a b c) -> LayoutClassScope #() -> LayoutEmptyScope
where the LayoutForkScope would have sidescopes: LayoutForkScope sideScopes: { LayoutTraitScope #(f) -> LayoutEmptyScope }
Then the classbuilder will build classes by always following the public path. Sidescopes aren't public. When you compile methods on the trait, its scopes are public; but when they are installed, they aren't public since they are sidescopes.
However, every method is compiled on the trait or class that provided the selector, so when you install the trait-related method, it will see the state related to the trait. And when the trait is installed, the sidescopes are actually copies of the original traitscope, so the actual fieldindices are updated in the LayoutTraitScope when it's installed.
Then how methods get updated based on state changes is at the moment completely unrelated to the trait implementation, since methods are already updated in my class builder based on a MethodModificationModel that knows how the fields have changed. This will use the decompiler/bytecode modification/recompiler to update the methods in place.
The only thing that I forgot to do until now is to actually modify all the classes that use a trait, every time the state of a trait changes... But that's straightforward. We just have to ask for the users of the stateful trait and reapply their class modification. That's all nicely modeled already.
As for overlapping state from multiple stateful traits.... there is no overlapping state since all state is private to the trait! You can use 2 traits with same slot names. This is no problem at all since the state is only seen by that trait. And their methods are only compiled on that trait, so the methods will always know exactly which of the slots you are referring to.
I hope this helps somehow :) Otherwise ... wait for the paper ;)
cheers, Toon
Indeed. And this is not different from changing a layout of a class having as impact that you have to update the methods. The default traits implementation already recompiles all methods anyway whenever it installs the trait. What I do is, I just let the trait compile itself on the subpart of the class that originally defined the trait.
allMethods from where?
Since this subpart is a copy of the original trait (just like the default traits does), it also has a COPY of the original layout. In this copy, the indices of the slots are updated when they are mixed with the class that is going to use the trait. So it's being compiled in the scope of the installed version of the trait-layout. So that easily works.
Yes, no big challenge to make it work. I agree. Put a ref to copydown, from strongtalk. Cheers, Alexandre
cheers
On 3 Apr 2011, at 06:23, Toon Verwaest wrote:
How are you dealing with the fact that the application of trait with state may change the layout of the class user and that you should recompile all the class method to deal with that. And if you have two traits having state you should do the same but for the traits themselves. So this means that the method in the traits cannot be reused (ok now we do not reuse them anymore sniff it was a nice model - reuse without cost of duplication).
How your layout object helps you for that? This is why I want first class slot :)
Stef I don't think I fully understand what you are saying...
The model is like this at the moment:
Every class has a layout attached to it. Layouts that have slots have LayoutScopes. For example, if you have
Class A super: Object slots: #(a b c) Class B super: A slots: #(d e)
Then you get
Class A<-> PointerLayout -> LayoutClassScope #(a b c) -> LayoutClassScope #() -> LayoutEmptyScope Class B<-> PointerLayout -> LayoutClassScope #(d e) -> LayoutClassScope #(a b c) -> LayoutClassScope #() -> LayoutEmptyScope
where LayoutClassScope #(a b c) is shared between the scope of B and the layout of A. The empty LayoutClassScope comes from Object and is shared as well.
Now if you get a stateful trait, a stateful trait C with slots #(f) looks like this:
StatefulTrait C<-> PointerLayout -> LayoutTraitScope #(f) -> LayoutEmptyScope
If you were to install the trait C on B, it would become:
Class B<-> PointerLayout -> LayoutClassScope #(d e) -> LayoutForkScope -> LayoutClassScope #(a b c) -> LayoutClassScope #() -> LayoutEmptyScope
where the LayoutForkScope would have sidescopes: LayoutForkScope sideScopes: { LayoutTraitScope #(f) -> LayoutEmptyScope }
Then the classbuilder will build classes by always following the public path. Sidescopes aren't public. When you compile methods on the trait, its scopes are public; but when they are installed, they aren't public since they are sidescopes.
However, every method is compiled on the trait or class that provided the selector, so when you install the trait-related method, it will see the state related to the trait. And when the trait is installed, the sidescopes are actually copies of the original traitscope, so the actual fieldindices are updated in the LayoutTraitScope when it's installed.
Then how methods get updated based on state changes is at the moment completely unrelated to the trait implementation, since methods are already updated in my class builder based on a MethodModificationModel that knows how the fields have changed. This will use the decompiler/bytecode modification/recompiler to update the methods in place.
The only thing that I forgot to do until now is to actually modify all the classes that use a trait, every time the state of a trait changes... But that's straightforward. We just have to ask for the users of the stateful trait and reapply their class modification. That's all nicely modeled already.
As for overlapping state from multiple stateful traits.... there is no overlapping state since all state is private to the trait! You can use 2 traits with same slot names. This is no problem at all since the state is only seen by that trait. And their methods are only compiled on that trait, so the methods will always know exactly which of the slots you are referring to.
I hope this helps somehow :) Otherwise ... wait for the paper ;)
cheers, Toon
-- _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.
On 04/03/2011 02:37 PM, Alexandre Bergel wrote:
Indeed. And this is not different from changing a layout of a class having as impact that you have to update the methods. The default traits implementation already recompiles all methods anyway whenever it installs the trait. What I do is, I just let the trait compile itself on the subpart of the class that originally defined the trait. allMethods from where? The methods coming from the trait are recompiled on the class when they are installed. Actually this should just do bytecode rewriting... but I don't have time to completely rewrite the traits just yet. I'll do that in May I guess ;) Put a ref to copydown, from strongtalk. Will do ;)
Now I fixed the bug in MC, the PlayOut project. Now it works; you can define an instance variable from a trait also on the class and they will not overlap. cheers, Toon
On 04/03/2011 02:29 PM, Alexandre Bergel wrote:
I guess that what Stef meant is the following: One of the problems when sharing code among mixin and stateful-trait application is that the physical layout of instances varies between mixin applications. (Section 6.5 of http://bergel.eu/download/papers/Berg07e-StatefulTraits.pdf) So as your paper states ... methods may have to be copied down if the layout is different. In the case of traits you always flatten out methods; and the default traits implementation for Pharo ALWAYS recompiles the methods when copying them. I just make sure they get recompiled in the installed trait's scope.
Of course in our case there is no such thing as "copying down", since traits are flattened, and not part of the hierarchy, such as is the case for mixins. So no difficult transformations are required, recompiling is good enough. It would be faster to just update the bytecode indices by decompiling and recompiling; but as said before ... that's just work I can't really afford at this very moment. cheers, Toon
Thanks I should digest it. Now what I did not like in our stateful model was that - in introduced too many operators - I'm not sure I like trait state to be private because it changes a lot the smalltalk model - the initialization is not modular so you end up write a lot of pattern initializeTrait and calling it. How you model deal with initialization beside using initform a la clos (because you have first class slots ... that I want in pharo -- see the subliminal message). Stef On Apr 3, 2011, at 12:23 PM, Toon Verwaest wrote:
How are you dealing with the fact that the application of trait with state may change the layout of the class user and that you should recompile all the class method to deal with that. And if you have two traits having state you should do the same but for the traits themselves. So this means that the method in the traits cannot be reused (ok now we do not reuse them anymore sniff it was a nice model - reuse without cost of duplication).
How your layout object helps you for that? This is why I want first class slot :)
Stef I don't think I fully understand what you are saying...
The model is like this at the moment:
Every class has a layout attached to it. Layouts that have slots have LayoutScopes. For example, if you have
Class A super: Object slots: #(a b c) Class B super: A slots: #(d e)
Then you get
Class A <-> PointerLayout -> LayoutClassScope #(a b c) -> LayoutClassScope #() -> LayoutEmptyScope Class B <-> PointerLayout -> LayoutClassScope #(d e) -> LayoutClassScope #(a b c) -> LayoutClassScope #() -> LayoutEmptyScope
where LayoutClassScope #(a b c) is shared between the scope of B and the layout of A. The empty LayoutClassScope comes from Object and is shared as well.
Now if you get a stateful trait, a stateful trait C with slots #(f) looks like this:
StatefulTrait C <-> PointerLayout -> LayoutTraitScope #(f) -> LayoutEmptyScope
If you were to install the trait C on B, it would become:
Class B <-> PointerLayout -> LayoutClassScope #(d e) -> LayoutForkScope -> LayoutClassScope #(a b c) -> LayoutClassScope #() -> LayoutEmptyScope
where the LayoutForkScope would have sidescopes: LayoutForkScope sideScopes: { LayoutTraitScope #(f) -> LayoutEmptyScope }
Then the classbuilder will build classes by always following the public path. Sidescopes aren't public. When you compile methods on the trait, its scopes are public; but when they are installed, they aren't public since they are sidescopes.
However, every method is compiled on the trait or class that provided the selector, so when you install the trait-related method, it will see the state related to the trait. And when the trait is installed, the sidescopes are actually copies of the original traitscope, so the actual fieldindices are updated in the LayoutTraitScope when it's installed.
Then how methods get updated based on state changes is at the moment completely unrelated to the trait implementation, since methods are already updated in my class builder based on a MethodModificationModel that knows how the fields have changed. This will use the decompiler/bytecode modification/recompiler to update the methods in place.
The only thing that I forgot to do until now is to actually modify all the classes that use a trait, every time the state of a trait changes... But that's straightforward. We just have to ask for the users of the stateful trait and reapply their class modification. That's all nicely modeled already.
As for overlapping state from multiple stateful traits.... there is no overlapping state since all state is private to the trait! You can use 2 traits with same slot names. This is no problem at all since the state is only seen by that trait. And their methods are only compiled on that trait, so the methods will always know exactly which of the slots you are referring to.
I hope this helps somehow :) Otherwise ... wait for the paper ;)
cheers, Toon
On 04/03/2011 04:58 PM, Stéphane Ducasse wrote:
Thanks I should digest it. Now what I did not like in our stateful model was that - in introduced too many operators - I'm not sure I like trait state to be private because it changes a lot the smalltalk model I'm not sure if it changes smalltalk too much! I'd rather say that it stays very much the same. When you weave in a stateful trait it's like weaving in a stateless trait, only behavior is added (from the point of view of the class). As for the extra operators, I'm not sure how weighty the aliasing of state from traits will be... I hope we can limit it. - the initialization is not modular so you end up write a lot of pattern initializeTrait and calling it.
How you model deal with initialization beside using initform a la clos (because you have first class slots ... that I want in pharo -- see the subliminal message). Stef The idea is that slots define how they should be initialized. This could be just a value like in CLOS, but is preferably something a lot more elaborate.
Another very cool thing that we can do now (which would require 3 lines of change in my system though), is that the slot can also be responsible for instance migration. There are four cases: 1- the instance variable didn't exist and now it does 2- the instance variable existed but disappeared 3- the metaobject changed (new semantics) 4- the metaobject stayed the same Basically the only case that is "handled" by standard Pharo is case 1; and what you do there is putting nil in the field. In our model the slot could do something more interesting when it's migrating the instances. And we could tackle the other cases too. I think it's starting to get ideal to implement an active context on top ;-) cheers, Toon
On Apr 3, 2011, at 12:23 PM, Toon Verwaest wrote:
How are you dealing with the fact that the application of trait with state may change the layout of the class user and that you should recompile all the class method to deal with that. And if you have two traits having state you should do the same but for the traits themselves. So this means that the method in the traits cannot be reused (ok now we do not reuse them anymore sniff it was a nice model - reuse without cost of duplication).
How your layout object helps you for that? This is why I want first class slot :)
Stef I don't think I fully understand what you are saying...
The model is like this at the moment:
Every class has a layout attached to it. Layouts that have slots have LayoutScopes. For example, if you have
Class A super: Object slots: #(a b c) Class B super: A slots: #(d e)
Then you get
Class A<-> PointerLayout -> LayoutClassScope #(a b c) -> LayoutClassScope #() -> LayoutEmptyScope Class B<-> PointerLayout -> LayoutClassScope #(d e) -> LayoutClassScope #(a b c) -> LayoutClassScope #() -> LayoutEmptyScope
where LayoutClassScope #(a b c) is shared between the scope of B and the layout of A. The empty LayoutClassScope comes from Object and is shared as well.
Now if you get a stateful trait, a stateful trait C with slots #(f) looks like this:
StatefulTrait C<-> PointerLayout -> LayoutTraitScope #(f) -> LayoutEmptyScope
If you were to install the trait C on B, it would become:
Class B<-> PointerLayout -> LayoutClassScope #(d e) -> LayoutForkScope -> LayoutClassScope #(a b c) -> LayoutClassScope #() -> LayoutEmptyScope
where the LayoutForkScope would have sidescopes: LayoutForkScope sideScopes: { LayoutTraitScope #(f) -> LayoutEmptyScope }
Then the classbuilder will build classes by always following the public path. Sidescopes aren't public. When you compile methods on the trait, its scopes are public; but when they are installed, they aren't public since they are sidescopes.
However, every method is compiled on the trait or class that provided the selector, so when you install the trait-related method, it will see the state related to the trait. And when the trait is installed, the sidescopes are actually copies of the original traitscope, so the actual fieldindices are updated in the LayoutTraitScope when it's installed.
Then how methods get updated based on state changes is at the moment completely unrelated to the trait implementation, since methods are already updated in my class builder based on a MethodModificationModel that knows how the fields have changed. This will use the decompiler/bytecode modification/recompiler to update the methods in place.
The only thing that I forgot to do until now is to actually modify all the classes that use a trait, every time the state of a trait changes... But that's straightforward. We just have to ask for the users of the stateful trait and reapply their class modification. That's all nicely modeled already.
As for overlapping state from multiple stateful traits.... there is no overlapping state since all state is private to the trait! You can use 2 traits with same slot names. This is no problem at all since the state is only seen by that trait. And their methods are only compiled on that trait, so the methods will always know exactly which of the slots you are referring to.
I hope this helps somehow :) Otherwise ... wait for the paper ;)
cheers, Toon
Thanks I should digest it. Now what I did not like in our stateful model was that - in introduced too many operators - I'm not sure I like trait state to be private because it changes a lot the smalltalk model
At least, Toon will avoid all the problems we had with the renaming and unwanted name clashed. Trait's accessors and mutators should then do their job. Alexandre
I'm not sure if it changes smalltalk too much! I'd rather say that it stays very much the same. When you weave in a stateful trait it's like weaving in a stateless trait, only behavior is added (from the point of view of the class). As for the extra operators, I'm not sure how weighty the aliasing of state from traits will be... I hope we can limit it.
- the initialization is not modular so you end up write a lot of pattern initializeTrait and calling it.
How you model deal with initialization beside using initform a la clos (because you have first class slots ... that I want in pharo -- see the subliminal message). Stef The idea is that slots define how they should be initialized. This could be just a value like in CLOS, but is preferably something a lot more elaborate.
Another very cool thing that we can do now (which would require 3 lines of change in my system though), is that the slot can also be responsible for instance migration. There are four cases: 1- the instance variable didn't exist and now it does 2- the instance variable existed but disappeared 3- the metaobject changed (new semantics) 4- the metaobject stayed the same
Basically the only case that is "handled" by standard Pharo is case 1; and what you do there is putting nil in the field. In our model the slot could do something more interesting when it's migrating the instances. And we could tackle the other cases too. I think it's starting to get ideal to implement an active context on top ;-)
cheers, Toon
On Apr 3, 2011, at 12:23 PM, Toon Verwaest wrote:
How are you dealing with the fact that the application of trait with state may change the layout of the class user and that you should recompile all the class method to deal with that. And if you have two traits having state you should do the same but for the traits themselves. So this means that the method in the traits cannot be reused (ok now we do not reuse them anymore sniff it was a nice model - reuse without cost of duplication).
How your layout object helps you for that? This is why I want first class slot :)
Stef I don't think I fully understand what you are saying...
The model is like this at the moment:
Every class has a layout attached to it. Layouts that have slots have LayoutScopes. For example, if you have
Class A super: Object slots: #(a b c) Class B super: A slots: #(d e)
Then you get
Class A<-> PointerLayout -> LayoutClassScope #(a b c) -> LayoutClassScope #() -> LayoutEmptyScope Class B<-> PointerLayout -> LayoutClassScope #(d e) -> LayoutClassScope #(a b c) -> LayoutClassScope #() -> LayoutEmptyScope
where LayoutClassScope #(a b c) is shared between the scope of B and the layout of A. The empty LayoutClassScope comes from Object and is shared as well.
Now if you get a stateful trait, a stateful trait C with slots #(f) looks like this:
StatefulTrait C<-> PointerLayout -> LayoutTraitScope #(f) -> LayoutEmptyScope
If you were to install the trait C on B, it would become:
Class B<-> PointerLayout -> LayoutClassScope #(d e) -> LayoutForkScope -> LayoutClassScope #(a b c) -> LayoutClassScope #() -> LayoutEmptyScope
where the LayoutForkScope would have sidescopes: LayoutForkScope sideScopes: { LayoutTraitScope #(f) -> LayoutEmptyScope }
Then the classbuilder will build classes by always following the public path. Sidescopes aren't public. When you compile methods on the trait, its scopes are public; but when they are installed, they aren't public since they are sidescopes.
However, every method is compiled on the trait or class that provided the selector, so when you install the trait-related method, it will see the state related to the trait. And when the trait is installed, the sidescopes are actually copies of the original traitscope, so the actual fieldindices are updated in the LayoutTraitScope when it's installed.
Then how methods get updated based on state changes is at the moment completely unrelated to the trait implementation, since methods are already updated in my class builder based on a MethodModificationModel that knows how the fields have changed. This will use the decompiler/bytecode modification/recompiler to update the methods in place.
The only thing that I forgot to do until now is to actually modify all the classes that use a trait, every time the state of a trait changes... But that's straightforward. We just have to ask for the users of the stateful trait and reapply their class modification. That's all nicely modeled already.
As for overlapping state from multiple stateful traits.... there is no overlapping state since all state is private to the trait! You can use 2 traits with same slot names. This is no problem at all since the state is only seen by that trait. And their methods are only compiled on that trait, so the methods will always know exactly which of the slots you are referring to.
I hope this helps somehow :) Otherwise ... wait for the paper ;)
cheers, Toon
-- _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.
On 04/03/2011 06:46 PM, Alexandre Bergel wrote:
Thanks I should digest it. Now what I did not like in our stateful model was that - in introduced too many operators - I'm not sure I like trait state to be private because it changes a lot the smalltalk model At least, Toon will avoid all the problems we had with the renaming and unwanted name clashed. Trait's accessors and mutators should then do their job.
Alexandre And since we would apply slot aliasing, we only need to provide the alias to the users. It's an extra way of weaving traits, not just getter+setter anymore. This means that they don't become public accessors! The slots are used for private access.
Toon
I want to read the paper :) Stef
Thanks I should digest it. Now what I did not like in our stateful model was that - in introduced too many operators - I'm not sure I like trait state to be private because it changes a lot the smalltalk model At least, Toon will avoid all the problems we had with the renaming and unwanted name clashed. Trait's accessors and mutators should then do their job.
Alexandre And since we would apply slot aliasing, we only need to provide the alias to the users. It's an extra way of weaving traits, not just getter+setter anymore. This means that they don't become public accessors! The slots are used for private access.
Toon
Another very cool thing that we can do now (which would require 3 lines of change in my system though), is that the slot can also be responsible for instance migration. There are four cases: 1- the instance variable didn't exist and now it does 2- the instance variable existed but disappeared 3- the metaobject changed (new semantics) 4- the metaobject stayed the same
Did you check the work of fred rivard because he was managing the dynamic change of class and managing slot reinitialization?
Basically the only case that is "handled" by standard Pharo is case 1; and what you do there is putting nil in the field. In our model the slot could do something more interesting when it's migrating the instances. And we could tackle the other cases too. I think it's starting to get ideal to implement an active context on top ;-)
cheers, Toon
On 04/04/2011 05:55 PM, Stéphane Ducasse wrote:
Another very cool thing that we can do now (which would require 3 lines of change in my system though), is that the slot can also be responsible for instance migration. There are four cases: 1- the instance variable didn't exist and now it does 2- the instance variable existed but disappeared 3- the metaobject changed (new semantics) 4- the metaobject stayed the same
Did you check the work of fred rivard because he was managing the dynamic change of class and managing slot reinitialization? Nope! Thanks for the link. It's just a very small part of my paper anyway; so it's good to have a more elaborate reference. Basically this is where I'd like to plug in active context.
Do you have an exact reference on this? On 04/04/2011 05:55 PM, Stéphane Ducasse wrote:
Another very cool thing that we can do now (which would require 3 lines of change in my system though), is that the slot can also be responsible for instance migration. There are four cases: 1- the instance variable didn't exist and now it does 2- the instance variable existed but disappeared 3- the metaobject changed (new semantics) 4- the metaobject stayed the same
Did you check the work of fred rivard because he was managing the dynamic change of class and managing slot reinitialization?
Basically the only case that is "handled" by standard Pharo is case 1; and what you do there is putting nil in the field. In our model the slot could do something more interesting when it's migrating the instances. And we could tackle the other cases too. I think it's starting to get ideal to implement an active context on top ;-)
cheers, Toon
he he. I am not sure Fred wrote in English. http://scg.unibe.ch/scgbib?_k=qQPhJdNf&query=rivard Cheers, Alexandre On 4 Apr 2011, at 14:15, Toon Verwaest wrote:
Do you have an exact reference on this?
On 04/04/2011 05:55 PM, Stéphane Ducasse wrote:
Another very cool thing that we can do now (which would require 3 lines of change in my system though), is that the slot can also be responsible for instance migration. There are four cases: 1- the instance variable didn't exist and now it does 2- the instance variable existed but disappeared 3- the metaobject changed (new semantics) 4- the metaobject stayed the same
Did you check the work of fred rivard because he was managing the dynamic change of class and managing slot reinitialization?
Basically the only case that is "handled" by standard Pharo is case 1; and what you do there is putting nil in the field. In our model the slot could do something more interesting when it's migrating the instances. And we could tackle the other cases too. I think it's starting to get ideal to implement an active context on top ;-)
cheers, Toon
-- _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.
I do read French too, no problem. I'm having a look at http://fredrivard.ifrance.com/fredrivard/pub/dicl/dicl.ps That seems related. On 04/04/2011 09:20 PM, Alexandre Bergel wrote:
he he. I am not sure Fred wrote in English. http://scg.unibe.ch/scgbib?_k=qQPhJdNf&query=rivard
Cheers, Alexandre
On 4 Apr 2011, at 14:15, Toon Verwaest wrote:
Do you have an exact reference on this?
On 04/04/2011 05:55 PM, Stéphane Ducasse wrote:
Another very cool thing that we can do now (which would require 3 lines of change in my system though), is that the slot can also be responsible for instance migration. There are four cases: 1- the instance variable didn't exist and now it does 2- the instance variable existed but disappeared 3- the metaobject changed (new semantics) 4- the metaobject stayed the same
Did you check the work of fred rivard because he was managing the dynamic change of class and managing slot reinitialization?
Basically the only case that is "handled" by standard Pharo is case 1; and what you do there is putting nil in the field. In our model the slot could do something more interesting when it's migrating the instances. And we could tackle the other cases too. I think it's starting to get ideal to implement an active context on top ;-)
cheers, Toon
In fact he got a better changeClassToThatOf: implementation and got kind of initform for slots. Stef
I do read French too, no problem.
I'm having a look at
http://fredrivard.ifrance.com/fredrivard/pub/dicl/dicl.ps
That seems related.
On 04/04/2011 09:20 PM, Alexandre Bergel wrote:
he he. I am not sure Fred wrote in English. http://scg.unibe.ch/scgbib?_k=qQPhJdNf&query=rivard
Cheers, Alexandre
On 4 Apr 2011, at 14:15, Toon Verwaest wrote:
Do you have an exact reference on this?
On 04/04/2011 05:55 PM, Stéphane Ducasse wrote:
Another very cool thing that we can do now (which would require 3 lines of change in my system though), is that the slot can also be responsible for instance migration. There are four cases: 1- the instance variable didn't exist and now it does 2- the instance variable existed but disappeared 3- the metaobject changed (new semantics) 4- the metaobject stayed the same
Did you check the work of fred rivard because he was managing the dynamic change of class and managing slot reinitialization?
Basically the only case that is "handled" by standard Pharo is case 1; and what you do there is putting nil in the field. In our model the slot could do something more interesting when it's migrating the instances. And we could tackle the other cases too. I think it's starting to get ideal to implement an active context on top ;-)
cheers, Toon
I remember Fred has lazy initialization of variable. All variables are lazy initialized. This means that variables set to nil when you change the class are lazy initialized. It has been a long time I looked at it. Alexandre On 4 Apr 2011, at 16:32, Stéphane Ducasse wrote:
In fact he got a better changeClassToThatOf: implementation and got kind of initform for slots.
Stef
I do read French too, no problem.
I'm having a look at
http://fredrivard.ifrance.com/fredrivard/pub/dicl/dicl.ps
That seems related.
On 04/04/2011 09:20 PM, Alexandre Bergel wrote:
he he. I am not sure Fred wrote in English. http://scg.unibe.ch/scgbib?_k=qQPhJdNf&query=rivard
Cheers, Alexandre
On 4 Apr 2011, at 14:15, Toon Verwaest wrote:
Do you have an exact reference on this?
On 04/04/2011 05:55 PM, Stéphane Ducasse wrote:
Another very cool thing that we can do now (which would require 3 lines of change in my system though), is that the slot can also be responsible for instance migration. There are four cases: 1- the instance variable didn't exist and now it does 2- the instance variable existed but disappeared 3- the metaobject changed (new semantics) 4- the metaobject stayed the same
Did you check the work of fred rivard because he was managing the dynamic change of class and managing slot reinitialization?
Basically the only case that is "handled" by standard Pharo is case 1; and what you do there is putting nil in the field. In our model the slot could do something more interesting when it's migrating the instances. And we could tackle the other cases too. I think it's starting to get ideal to implement an active context on top ;-)
cheers, Toon
-- _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.
Yes, I read those two things too... but it doesn't seem like a giant leap of an improvement :) On 04/05/2011 02:34 PM, Alexandre Bergel wrote:
I remember Fred has lazy initialization of variable. All variables are lazy initialized. This means that variables set to nil when you change the class are lazy initialized. It has been a long time I looked at it.
Alexandre
On 4 Apr 2011, at 16:32, Stéphane Ducasse wrote:
In fact he got a better changeClassToThatOf: implementation and got kind of initform for slots.
Stef
I do read French too, no problem.
I'm having a look at
http://fredrivard.ifrance.com/fredrivard/pub/dicl/dicl.ps
That seems related.
On 04/04/2011 09:20 PM, Alexandre Bergel wrote:
he he. I am not sure Fred wrote in English. http://scg.unibe.ch/scgbib?_k=qQPhJdNf&query=rivard
Cheers, Alexandre
On 4 Apr 2011, at 14:15, Toon Verwaest wrote:
Do you have an exact reference on this?
On 04/04/2011 05:55 PM, Stéphane Ducasse wrote:
Another very cool thing that we can do now (which would require 3 lines of change in my system though), is that the slot can also be responsible for instance migration. There are four cases: 1- the instance variable didn't exist and now it does 2- the instance variable existed but disappeared 3- the metaobject changed (new semantics) 4- the metaobject stayed the same
Did you check the work of fred rivard because he was managing the dynamic change of class and managing slot reinitialization?
Basically the only case that is "handled" by standard Pharo is case 1; and what you do there is putting nil in the field. In our model the slot could do something more interesting when it's migrating the instances. And we could tackle the other cases too. I think it's starting to get ideal to implement an active context on top ;-)
cheers, Toon
Did you check the work of fred rivard because he was managing the dynamic change of class and managing slot reinitialization? As far as I can tell from his paper he's mostly interested in the "accept instance" to modify instances from one class to another. This forces you to write the full mapping yourself in each class (from old to new). The idea of my migration is rather that the slots themselves are responsible. So this migration behavior is generally shared on slot-level. Default behavior is to just copy all the related fields.
In his example it makes sense to script the whole class, since the whole class is only related semantically to what he wants to change; but I guess in most cases there are only small fragments of your class that need special care. Or the whole thing will require such elaborate care that you need waaaay bigger systems (like active context). Just my 2cents. I might have misunderstood it though :)
I tried the image. I hadn't seen such a look for years :-) StatefulTrait named: #TStatefulTest layout: PointerLayout slots: { #tfirst => Slot. #tsecond => Slot. } uses: {} category: #'Slot-Traits-Test' I checked what layout: is about. StatefulTrait is a dry in terms of comments :-) Why do you have "=> Slot" ? What can tfirst be else, if not a slot? Can you specialize the slots to use a particular layout? I played a bit with your image. I cannot access tfirst in MyFirstTest. Your implementation is conform to the policy you defined above. Your image is a bit unstable. I tried to press the tab key for autocompletion, and got some debuggers that I couldn't close. I misspelled aMethod with aMethdo, and got plenty of debuggers related to QQParser Cheers, Alexandre On 3 Apr 2011, at 05:34, Toon Verwaest wrote:
Oh yes.. I am :)
http://pinocchio.unibe.ch/~tverwaes/slots.tar.gz gives you an image with an example of a stateful trait open. The state is always private to the class / trait at the moment and it already seems to work pretty well. I modified the NewInspector slightly to show you the proper data (although this needs to be cleaned up, and state should be sorted per trait), and the OB to compile and syntax highlight in the right context.
I didn't test more complex examples yet than what's open, but it's designed generically enough that I'm confident it does ... euhm ... ;)
cheers, Toon
On 04/03/2011 10:44 AM, Stéphane Ducasse wrote:
On Apr 2, 2011, at 9:10 PM, Toon Verwaest wrote:
Hi all,
as you know I'm working on stateful traits using my new classbuilder no Are you?
etc... Now I noticed that methods are highlighted always inside of the context of the class that's active in the class browser. How can I change this? There is already a useful method around to figure out which object it belongs to:
SomeClass traitOrClassOfSelector: #aMethod
This actually will tell me which trait it comes from. So now I could apply syntax coloring in the context of the trait rather than the class. Since in my implementation state is all private to the trait / class, they should be able to access their own state but not see the state of the other class. This obviously also means that coloring should happen in the correct scope, rather than always in the scope of the class.
At the moment the coloring doesn't really make sense ... but then it didn't really matter that much until now. Although if you try to access state in a method coming from a trait, while coding in your IDE you'll probably have the impression you can access your local instvars. I don't really know what the semantics are there... but it seems a bit broken :)
cheers, Toon
-- _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.
I just finished building a new image based on the helvetia image. http://pinocchio.unibe.ch/~tverwaes/PlayOut.tar.gz The previous image is what I've been developing in, and yes, it's pretty annoying... I hope that the new image will perform better. But since I already noticed that the new inspector isn't loaded, you don't get a proper view on the trait-related objects. Coloring is still done properly though. Yes I see, I did forget to implement all the tools to make it work. You know... I started the stateful traits implementation on Friday... I'm glad that I'm as far as I am ;) However, in the new image I can close it. Exceptions are just very slow for some reason. There are not many comments around, and not enough tests. After I finish my paperwriting I'll go over it and document everything! It's a sneak preview ... did I mention that? ;) For the slots, yes there are subclasses of the standard Slot class; and they can provide non-standard access. You might notice that changing a class' layout is a lot faster thanks to bytecode level method updates :) Or not, hence I mention it again. That's all part of this particular image. cheers, Toon On 04/03/2011 02:19 PM, Alexandre Bergel wrote:
I tried the image. I hadn't seen such a look for years :-)
StatefulTrait named: #TStatefulTest layout: PointerLayout slots: { #tfirst => Slot. #tsecond => Slot. } uses: {} category: #'Slot-Traits-Test'
I checked what layout: is about. StatefulTrait is a dry in terms of comments :-) Why do you have "=> Slot" ? What can tfirst be else, if not a slot? Can you specialize the slots to use a particular layout?
I played a bit with your image. I cannot access tfirst in MyFirstTest. Your implementation is conform to the policy you defined above.
Your image is a bit unstable. I tried to press the tab key for autocompletion, and got some debuggers that I couldn't close. I misspelled aMethod with aMethdo, and got plenty of debuggers related to QQParser
Cheers, Alexandre
On 3 Apr 2011, at 05:34, Toon Verwaest wrote:
Oh yes.. I am :)
http://pinocchio.unibe.ch/~tverwaes/slots.tar.gz gives you an image with an example of a stateful trait open. The state is always private to the class / trait at the moment and it already seems to work pretty well. I modified the NewInspector slightly to show you the proper data (although this needs to be cleaned up, and state should be sorted per trait), and the OB to compile and syntax highlight in the right context.
I didn't test more complex examples yet than what's open, but it's designed generically enough that I'm confident it does ... euhm ... ;)
cheers, Toon
On 04/03/2011 10:44 AM, Stéphane Ducasse wrote:
On Apr 2, 2011, at 9:10 PM, Toon Verwaest wrote:
Hi all,
as you know I'm working on stateful traits using my new classbuilder no Are you?
etc... Now I noticed that methods are highlighted always inside of the context of the class that's active in the class browser. How can I change this? There is already a useful method around to figure out which object it belongs to:
SomeClass traitOrClassOfSelector: #aMethod
This actually will tell me which trait it comes from. So now I could apply syntax coloring in the context of the trait rather than the class. Since in my implementation state is all private to the trait / class, they should be able to access their own state but not see the state of the other class. This obviously also means that coloring should happen in the correct scope, rather than always in the scope of the class.
At the moment the coloring doesn't really make sense ... but then it didn't really matter that much until now. Although if you try to access state in a method coming from a trait, while coding in your IDE you'll probably have the impression you can access your local instvars. I don't really know what the semantics are there... but it seems a bit broken :)
cheers, Toon
Yes I see, I did forget to implement all the tools to make it work. You know... I started the stateful traits implementation on Friday... I'm glad that I'm as far as I am ;) However, in the new image I can close it. Exceptions are just very slow for some reason.
This is cool that you're working on this topic.
There are not many comments around, and not enough tests. After I finish my paperwriting I'll go over it and document everything! It's a sneak preview ... did I mention that? ;)
Yes, papers are important. Papers are often more used than implementations. Cheers, Alexandre
For the slots, yes there are subclasses of the standard Slot class; and they can provide non-standard access.
You might notice that changing a class' layout is a lot faster thanks to bytecode level method updates :) Or not, hence I mention it again. That's all part of this particular image.
cheers, Toon
On 04/03/2011 02:19 PM, Alexandre Bergel wrote:
I tried the image. I hadn't seen such a look for years :-)
StatefulTrait named: #TStatefulTest layout: PointerLayout slots: { #tfirst => Slot. #tsecond => Slot. } uses: {} category: #'Slot-Traits-Test'
I checked what layout: is about. StatefulTrait is a dry in terms of comments :-) Why do you have "=> Slot" ? What can tfirst be else, if not a slot? Can you specialize the slots to use a particular layout?
I played a bit with your image. I cannot access tfirst in MyFirstTest. Your implementation is conform to the policy you defined above.
Your image is a bit unstable. I tried to press the tab key for autocompletion, and got some debuggers that I couldn't close. I misspelled aMethod with aMethdo, and got plenty of debuggers related to QQParser
Cheers, Alexandre
On 3 Apr 2011, at 05:34, Toon Verwaest wrote:
Oh yes.. I am :)
http://pinocchio.unibe.ch/~tverwaes/slots.tar.gz gives you an image with an example of a stateful trait open. The state is always private to the class / trait at the moment and it already seems to work pretty well. I modified the NewInspector slightly to show you the proper data (although this needs to be cleaned up, and state should be sorted per trait), and the OB to compile and syntax highlight in the right context.
I didn't test more complex examples yet than what's open, but it's designed generically enough that I'm confident it does ... euhm ... ;)
cheers, Toon
On 04/03/2011 10:44 AM, Stéphane Ducasse wrote:
On Apr 2, 2011, at 9:10 PM, Toon Verwaest wrote:
Hi all,
as you know I'm working on stateful traits using my new classbuilder no Are you?
etc... Now I noticed that methods are highlighted always inside of the context of the class that's active in the class browser. How can I change this? There is already a useful method around to figure out which object it belongs to:
SomeClass traitOrClassOfSelector: #aMethod
This actually will tell me which trait it comes from. So now I could apply syntax coloring in the context of the trait rather than the class. Since in my implementation state is all private to the trait / class, they should be able to access their own state but not see the state of the other class. This obviously also means that coloring should happen in the correct scope, rather than always in the scope of the class.
At the moment the coloring doesn't really make sense ... but then it didn't really matter that much until now. Although if you try to access state in a method coming from a trait, while coding in your IDE you'll probably have the impression you can access your local instvars. I don't really know what the semantics are there... but it seems a bit broken :)
cheers, Toon
-- _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.
So now I could apply syntax coloring in the context of the trait rather than the class.
Do you mean coloring message sends in a trait's method? For self call that is not specified in the requirement?
Since in my implementation state is all private to the trait / class, they should be able to access their own state but not see the state of the other class. This obviously also means that coloring should happen in the correct scope, rather than always in the scope of the class.
Can you merge state? What happens with C.x uses T.x ? Methods of T will use T.x and methods of C will use C.x? Alexandre -- _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.
Do you mean coloring message sends in a trait's method? For self call that is not specified in the requirement? I meant that if you look at a method coming from a trait inside of the class browser; while your browser is pointing at a class. Instance variables were colored red since they weren't found on the class. However, they came from the trait, so should have been colored in the scope of the trait. Now that's fixed. All methods are being colored in the scope where they are defined. Can you merge state? What happens with C.x uses T.x ? Methods of T will use T.x and methods of C will use C.x?
Alexandre
At the moment you can't, but in our slot library we have alias slots. So that we could use to do the same tricks as with methods: required slots, provided slots, "defrosted slots", ... So yes, at the moment C.x using T.x will have completely separate uses in methods, only dependent on where they are compiled. Traits related methods see the trait state, class related methods see the class state. I think it's more important to get that part working first; and to then start providing access, which is why I did it in this order. cheers, Toon
Can you merge state? What happens with C.x uses T.x ? Methods of T will use T.x and methods of C will use C.x?
At the moment you can't, but in our slot library we have alias slots. So that we could use to do the same tricks as with methods: required slots, provided slots, "defrosted slots", ...
I am lost. I understand that a trait have a class have a different scope of slots. But you cannot define C.x and T.x? Why? Cheers, Alexandre -- _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.
On 04/03/2011 02:31 PM, Alexandre Bergel wrote:
Can you merge state? What happens with C.x uses T.x ? Methods of T will use T.x and methods of C will use C.x?
At the moment you can't, but in our slot library we have alias slots. So that we could use to do the same tricks as with methods: required slots, provided slots, "defrosted slots", ... I am lost. I understand that a trait have a class have a different scope of slots. But you cannot define C.x and T.x? Why?
Cheers, Alexandre T.x and C.x will be different slots. That's all. Go ahead and try it out ;) Install some uniquely named accessor methods on the trait and class that use the same instance variable.
cheers
On 04/03/2011 02:31 PM, Alexandre Bergel wrote:
Can you merge state? What happens with C.x uses T.x ? Methods of T will use T.x and methods of C will use C.x?
At the moment you can't, but in our slot library we have alias slots. So that we could use to do the same tricks as with methods: required slots, provided slots, "defrosted slots", ... I am lost. I understand that a trait have a class have a different scope of slots. But you cannot define C.x and T.x? Why?
Cheers, Alexandre Doh, I see. There's a stupid test that raises a conflict cause it finds slots that are conflicting. While actually they are not conflicting. Let me fix that ;)
cheers, Toon
participants (3)
-
Alexandre Bergel -
Stéphane Ducasse -
Toon Verwaest