[Repost] 3.10 traits inconsistencies

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

[Repost] 3.10 traits inconsistencies

Andreas.Raab
Hi -

[Repost from a while ago. I'm still interested in finding out more about
these issues - who maintains traits these days?]

I noticed some traits inconsistencies in the latest 3.10 beta. If
someone could shed a light on those, I'd appreciate it:

* Class definitions with traits:

Class>>subclass: t uses: aTraitCompositionOrArray instanceVariableNames:
f classVariableNames: d poolDictionaries: s category: cat

says this:

   copyOfOldClass := self copy.
   newClass := self subclass: t instanceVariableNames: f
classVariableNames: d poolDictionaries: s category: cat.
   "..."
   SystemChangeNotifier uniqueInstance
        classDefinitionChangedFrom: copyOfOldClass to: newClass.

This seems wrong because unless I'm missing something the
"copyOfOldClass" is the superclass of the class being changed and not
its old representation. This pattern seems to appear in all traits
subclass creation methods.

* Class traits:

fooTrait := Trait named: #TFooTrait uses:{} category: 'Tests'.
barTrait := Trait named: #TBarTrait uses:{} category: 'Tests'.

classA := Object subclass: #TestClassA
   uses: fooTrait
   instanceVariableNames: ''
   classVariableNames: ''
   poolDictionaries: ''
   category: 'Tests'.
classA classTrait uses: fooTrait class + barTrait. "works"

classB := Object subclass: #TestClassB
   uses: fooTrait + barTrait
   instanceVariableNames: ''
   classVariableNames: ''
   poolDictionaries: ''
   category: 'Tests'.
classA classTrait uses: fooTrait class + barTrait. "fails"

Why is this? In particular considering that we can transform classA into
the desired shape via:

classA := Object subclass: #TestClassA
   uses: fooTrait
   instanceVariableNames: ''
   classVariableNames: ''
   poolDictionaries: ''
   category: 'Tests'.
classA classTrait uses: fooTrait class + barTrait. "works"
classA := Object subclass: #TestClassA
   uses: fooTrait + barTrait
   instanceVariableNames: ''
   classVariableNames: ''
   poolDictionaries: ''
   category: 'Tests'.

(note that in the above the obvious desire is to include the methods of
TFooTrait for both class and metaclass operations). Given that the
former doesn't work, I think this last example constitutes a bug. But
more importantly: What the rationale for disallowing the inclusion of
the same trait on both instance and class side?

* Fileouts:

I was trying to file out a bunch of code with traits and found that I
can't file it in again. I've tried with other code and, for example,
Nile can't be filed out and back in either (if you need something to try
it with). Monticello seems to work but at times this is a bit of a
heavy-weight solution. Any ideas?

Oh, and lastly: Is there any documentation at all about the the
implementation of the traits kernel? (not the general approach; I'm
pretty clear on that but rather on the implementation itself) I seem to
remember having seen references to a thesis maybe but I can't remember.
Any pointers welcome.

Cheers,
   - Andreas


Reply | Threaded
Open this post in threaded view
|

Re: [Repost] 3.10 traits inconsistencies

stephane ducasse
Hi andreas

sorry I'm too exhausted (I mean it literally -huge headhach) to reply  
today deeply, I had and will have some key deadlines and a house from  
1930 with electricians fixing all the wires (basically changing every  
single wires for our safety) so total mess for a couple of week  
starting....

In a couple of weeks I hope to get back to squeak and I would like to  
fix several little bugs in traits like the one that we found with  
damien during nile.

Adrian master is what you are looking for.
        http://www.iam.unibe.ch/~scg/Archive/Diploma/Lien04a.pdf
and I'm sure that adrian can reply to you .

So thanks for asking and I will try to reply but I will travelling  
again.

Stef

On 28 nov. 07, at 07:17, Andreas Raab wrote:

> Hi -
>
> [Repost from a while ago. I'm still interested in finding out more  
> about these issues - who maintains traits these days?]
>
> I noticed some traits inconsistencies in the latest 3.10 beta. If
> someone could shed a light on those, I'd appreciate it:
>
> * Class definitions with traits:
>
> Class>>subclass: t uses: aTraitCompositionOrArray  
> instanceVariableNames:
> f classVariableNames: d poolDictionaries: s category: cat
>
> says this:
>
>   copyOfOldClass := self copy.
>   newClass := self subclass: t instanceVariableNames: f
> classVariableNames: d poolDictionaries: s category: cat.
>   "..."
>   SystemChangeNotifier uniqueInstance
> classDefinitionChangedFrom: copyOfOldClass to: newClass.
>
> This seems wrong because unless I'm missing something the
> "copyOfOldClass" is the superclass of the class being changed and not
> its old representation. This pattern seems to appear in all traits
> subclass creation methods.
>
> * Class traits:
>
> fooTrait := Trait named: #TFooTrait uses:{} category: 'Tests'.
> barTrait := Trait named: #TBarTrait uses:{} category: 'Tests'.
>
> classA := Object subclass: #TestClassA
>   uses: fooTrait
>   instanceVariableNames: ''
>   classVariableNames: ''
>   poolDictionaries: ''
>   category: 'Tests'.
> classA classTrait uses: fooTrait class + barTrait. "works"
>
> classB := Object subclass: #TestClassB
>   uses: fooTrait + barTrait
>   instanceVariableNames: ''
>   classVariableNames: ''
>   poolDictionaries: ''
>   category: 'Tests'.
> classA classTrait uses: fooTrait class + barTrait. "fails"
>
> Why is this? In particular considering that we can transform classA  
> into
> the desired shape via:
>
> classA := Object subclass: #TestClassA
>   uses: fooTrait
>   instanceVariableNames: ''
>   classVariableNames: ''
>   poolDictionaries: ''
>   category: 'Tests'.
> classA classTrait uses: fooTrait class + barTrait. "works"
> classA := Object subclass: #TestClassA
>   uses: fooTrait + barTrait
>   instanceVariableNames: ''
>   classVariableNames: ''
>   poolDictionaries: ''
>   category: 'Tests'.
>
> (note that in the above the obvious desire is to include the  
> methods of
> TFooTrait for both class and metaclass operations). Given that the
> former doesn't work, I think this last example constitutes a bug. But
> more importantly: What the rationale for disallowing the inclusion of
> the same trait on both instance and class side?

normally this should not be a problem to use a traits from class and  
instance side.
At least this was never a limit of the model.

> * Fileouts:
>
> I was trying to file out a bunch of code with traits and found that I
> can't file it in again. I've tried with other code and, for example,
> Nile can't be filed out and back in either (if you need something  
> to try
> it with).

needs to be fixed :(
The code of fileout is so bad I always wanted to rewrite everything.

> Monticello seems to work but at times this is a bit of a
> heavy-weight solution. Any ideas?
>
> Oh, and lastly: Is there any documentation at all about the the
> implementation of the traits kernel? (not the general approach; I'm
> pretty clear on that but rather on the implementation itself) I  
> seem to
> remember having seen references to a thesis maybe but I can't  
> remember.
> Any pointers welcome.
>
> Cheers,
>   - Andreas
>
>
>


Reply | Threaded
Open this post in threaded view
|

Re: [Repost] 3.10 traits inconsistencies

Andreas.Raab
stephane ducasse wrote:
> Adrian master is what you are looking for.
>     http://www.iam.unibe.ch/~scg/Archive/Diploma/Lien04a.pdf
> and I'm sure that adrian can reply to you .

Thanks, this is exactly what I'm looking for.

Cheers,
   - Andreas

>
> So thanks for asking and I will try to reply but I will travelling again.
>
> Stef
>
> On 28 nov. 07, at 07:17, Andreas Raab wrote:
>
>> Hi -
>>
>> [Repost from a while ago. I'm still interested in finding out more
>> about these issues - who maintains traits these days?]
>>
>> I noticed some traits inconsistencies in the latest 3.10 beta. If
>> someone could shed a light on those, I'd appreciate it:
>>
>> * Class definitions with traits:
>>
>> Class>>subclass: t uses: aTraitCompositionOrArray instanceVariableNames:
>> f classVariableNames: d poolDictionaries: s category: cat
>>
>> says this:
>>
>>   copyOfOldClass := self copy.
>>   newClass := self subclass: t instanceVariableNames: f
>> classVariableNames: d poolDictionaries: s category: cat.
>>   "..."
>>   SystemChangeNotifier uniqueInstance
>>     classDefinitionChangedFrom: copyOfOldClass to: newClass.
>>
>> This seems wrong because unless I'm missing something the
>> "copyOfOldClass" is the superclass of the class being changed and not
>> its old representation. This pattern seems to appear in all traits
>> subclass creation methods.
>>
>> * Class traits:
>>
>> fooTrait := Trait named: #TFooTrait uses:{} category: 'Tests'.
>> barTrait := Trait named: #TBarTrait uses:{} category: 'Tests'.
>>
>> classA := Object subclass: #TestClassA
>>   uses: fooTrait
>>   instanceVariableNames: ''
>>   classVariableNames: ''
>>   poolDictionaries: ''
>>   category: 'Tests'.
>> classA classTrait uses: fooTrait class + barTrait. "works"
>>
>> classB := Object subclass: #TestClassB
>>   uses: fooTrait + barTrait
>>   instanceVariableNames: ''
>>   classVariableNames: ''
>>   poolDictionaries: ''
>>   category: 'Tests'.
>> classA classTrait uses: fooTrait class + barTrait. "fails"
>>
>> Why is this? In particular considering that we can transform classA into
>> the desired shape via:
>>
>> classA := Object subclass: #TestClassA
>>   uses: fooTrait
>>   instanceVariableNames: ''
>>   classVariableNames: ''
>>   poolDictionaries: ''
>>   category: 'Tests'.
>> classA classTrait uses: fooTrait class + barTrait. "works"
>> classA := Object subclass: #TestClassA
>>   uses: fooTrait + barTrait
>>   instanceVariableNames: ''
>>   classVariableNames: ''
>>   poolDictionaries: ''
>>   category: 'Tests'.
>>
>> (note that in the above the obvious desire is to include the methods of
>> TFooTrait for both class and metaclass operations). Given that the
>> former doesn't work, I think this last example constitutes a bug. But
>> more importantly: What the rationale for disallowing the inclusion of
>> the same trait on both instance and class side?
>
> normally this should not be a problem to use a traits from class and
> instance side.
> At least this was never a limit of the model.
>
>> * Fileouts:
>>
>> I was trying to file out a bunch of code with traits and found that I
>> can't file it in again. I've tried with other code and, for example,
>> Nile can't be filed out and back in either (if you need something to try
>> it with).
>
> needs to be fixed :(
> The code of fileout is so bad I always wanted to rewrite everything.
>
>> Monticello seems to work but at times this is a bit of a
>> heavy-weight solution. Any ideas?
>>
>> Oh, and lastly: Is there any documentation at all about the the
>> implementation of the traits kernel? (not the general approach; I'm
>> pretty clear on that but rather on the implementation itself) I seem to
>> remember having seen references to a thesis maybe but I can't remember.
>> Any pointers welcome.
>>
>> Cheers,
>>   - Andreas
>>
>>
>>
>
>
>


Reply | Threaded
Open this post in threaded view
|

Re: [Repost] 3.10 traits inconsistencies

Adrian Lienhard
In reply to this post by Andreas.Raab
Hi Andreas

I haven't got round to looking into this so far...

On Nov 28, 2007, at 07:17 , Andreas Raab wrote:

> Hi -
>
> [Repost from a while ago. I'm still interested in finding out more  
> about these issues - who maintains traits these days?]
>
> I noticed some traits inconsistencies in the latest 3.10 beta. If
> someone could shed a light on those, I'd appreciate it:
>
> * Class definitions with traits:
>
> Class>>subclass: t uses: aTraitCompositionOrArray  
> instanceVariableNames:
> f classVariableNames: d poolDictionaries: s category: cat
>
> says this:
>
>  copyOfOldClass := self copy.
>  newClass := self subclass: t instanceVariableNames: f
> classVariableNames: d poolDictionaries: s category: cat.
>  "..."
>  SystemChangeNotifier uniqueInstance
> classDefinitionChangedFrom: copyOfOldClass to: newClass.
>
> This seems wrong because unless I'm missing something the
> "copyOfOldClass" is the superclass of the class being changed and not
> its old representation. This pattern seems to appear in all traits
> subclass creation methods.

yes, this seems wrong. Not sure why the notification should be  
required here at all, since it should be triggered in  
ClassBuilder>>name:inEnvironment:...

>
> * Class traits:
>
> fooTrait := Trait named: #TFooTrait uses:{} category: 'Tests'.
> barTrait := Trait named: #TBarTrait uses:{} category: 'Tests'.
>
> classA := Object subclass: #TestClassA
>  uses: fooTrait
>  instanceVariableNames: ''
>  classVariableNames: ''
>  poolDictionaries: ''
>  category: 'Tests'.
> classA classTrait uses: fooTrait class + barTrait. "works"

I guess you mean:
classA class uses: fooTrait classTrait + barTrait
instanceVariableNames: ''

>
>
> classB := Object subclass: #TestClassB
>  uses: fooTrait + barTrait
>  instanceVariableNames: ''
>  classVariableNames: ''
>  poolDictionaries: ''
>  category: 'Tests'.
> classA classTrait uses: fooTrait class + barTrait. "fails"

and here instead:
classB class uses: fooTrait classTrait + barTrait  
instanceVariableNames: ''

The problem with is that you have the barTrait on the instance side  
and now you try to remove its associated trait on the class side  
(barTrait classTrait). This should be avoided since traits come always  
in pairs of instance and class side. If you add a trait on the  
instance side, its classTrait gets automatically added to the class  
side of this class or trait. An exception are traits that you only  
want to add to the class side. They cannot have methods on their class  
side.

What you want to do is probably:

classB class
        uses: fooTrait classTrait + barTrait classTrait + barTrait
        instanceVariableNames: ''


> Why is this? In particular considering that we can transform classA  
> into
> the desired shape via:
>
> classA := Object subclass: #TestClassA
>  uses: fooTrait
>  instanceVariableNames: ''
>  classVariableNames: ''
>  poolDictionaries: ''
>  category: 'Tests'.
> classA classTrait uses: fooTrait class + barTrait. "works"
> classA := Object subclass: #TestClassA
>  uses: fooTrait + barTrait
>  instanceVariableNames: ''
>  classVariableNames: ''
>  poolDictionaries: ''
>  category: 'Tests'.

yes, but there is a difference (see explanation above):

classA class traitComposition -->  TFooTrait classTrait + TBarTrait +  
TBarTrait classTrait

> (note that in the above the obvious desire is to include the methods  
> of
> TFooTrait for both class and metaclass operations). Given that the
> former doesn't work, I think this last example constitutes a bug. But
> more importantly: What the rationale for disallowing the inclusion of
> the same trait on both instance and class side?
>
> * Fileouts:
>
> I was trying to file out a bunch of code with traits and found that I
> can't file it in again. I've tried with other code and, for example,
> Nile can't be filed out and back in either (if you need something to  
> try
> it with). Monticello seems to work but at times this is a bit of a
> heavy-weight solution. Any ideas?

I agree, fileouts are sometimes handy. I implemented this but only  
used it sparingly. There is also a test, which is green. So apparently  
this is a bug.

Adrian

>
>
> Oh, and lastly: Is there any documentation at all about the the
> implementation of the traits kernel? (not the general approach; I'm
> pretty clear on that but rather on the implementation itself) I seem  
> to
> remember having seen references to a thesis maybe but I can't  
> remember.
> Any pointers welcome.
>
> Cheers,
>  - Andreas
>
>