On Dec 28, 2009, at 12:39 , Igor Stasenko wrote:

> 2009/12/28 Stéphane Ducasse <[email protected]>:
>>>>
>>>>
>>>> Package                 Classes         Methods
>>>> Traits                  59              873
>>>> Traits-Kernel           22              343
>>>> Traits-Kernel-Traits    17              215
>>>> Traits-Composition      7               127
>>>> NanoTraits-Kernel       9               190
>>>> NanoTraits-Tests        9               122

Haha. This table is nonsense:
- The package "Traits" includes "Traits-Kernel", "Traits-Composition"  
etc. so it is counting the same classes and methods twice
- The numbers are from an older implementation of Traits. In Pharo  
there is a refactored version with less traits that is easier to  
understand. Squeak has an old version.
- Methods defined in the traits ("Traits-Kernel-Traits") are also used  
by Behavior, ClassDescription, etc. hence making these classes smaller  
in turn (but the table does not show this fact)
- The requires algorithm is not directly related to Traits (as I  
pointed out in a recent mail)

In a Pharo 1.0 image I get

Package                 Classes         Methods
Traits-Kernel           11              343
Traits-Kernel-Traits    6               215
Traits-Composition      7               122

[...]

>> Igor please rephrase your thoughts! :)
>>        amount of complexity !!!
>>        not amount of code!!!
>>        Come on number of classes is not a decent measure in  
>> presence of late binding!
>>
>
> hehe.. i hope that Andreas writing short methods, not a fat ones which
> trying to do everything at once :)


Not sure about this. I browsed through the NanoTraits code for 2  
minutes, and one thing that puzzled me was this method:

!ClassDescription methodsFor: '*NanoTraits-Extensions' stamp: 'ar  
12/20/2009 13:38'!
installTraitsFrom: aTraitComposition
        "Install the traits from the given composition"
        | allTraits methods oldMethod removals oldCategories |
        (aTraitComposition isKindOf: NanoTraitComposition)
                ifFalse:[self error: 'Invalid composition'].
        (self traitComposition isEmpty and: [aTraitComposition isEmpty])  
ifTrue: [^self].

        "Check for cycles"
        allTraits := aTraitComposition gather: [:t | t allTraits copyWith: t].
        (allTraits includes: self) ifTrue:[^self error: 'Cyclic trait  
definition detected'].

        "XXXX: addUser/removeUser should be part of setter, but subclass
        override prevents it until we've got rid of Traits mess."
        self traitComposition removeTraitUser: self.
        self traitComposition: aTraitComposition.
        aTraitComposition addTraitUser: self.

        "Assemble the methods in a new dictionary first.
        Uses a Dictionary instead of a MethodDictionary for speed (MDs grow  
by #become:)"
        methods := Dictionary new.

        "Stick in the local methods first, since this avoids generating  
conflict methods unnecessarily"
        self selectorsAndMethodsDo:[:sel :newMethod|
                (self isLocalMethod: newMethod)
                        ifTrue:[methods at: sel put:newMethod]].

        "Now assemble the traits methods"
        aTraitComposition do:[:trait|
                trait selectorsAndMethodsDo:[:sel :newMethod|
                        oldMethod := methods at: sel ifAbsentPut:[newMethod].
                        newMethod == oldMethod ifFalse:["a conflict"
                                (self isLocalMethod: oldMethod) ifFalse:[
                                        methods at: sel put: (self 
resolveTraitsConflict: sel from:  
oldMethod to: newMethod).
                                ].
                        ].
                ].
        ].

        "Apply the changes. We first add the new or changed methods."
        oldCategories := Set new.
        methods keysAndValuesDo:[:sel :newMethod|
                oldMethod := self compiledMethodAt: sel ifAbsent:[nil].
                oldMethod == newMethod ifFalse:[
                        self traitAddSelector: sel withMethod: newMethod.
                        (self organization categoryOfElement: sel) 
ifNotNil:[:cat|  
oldCategories add: cat].
                        self organization classify: sel under:
                                (newMethod methodHome organization 
categoryOfElement: newMethod  
selector).
                ]].

        "Now remove the old or obsoleted ones"
        removals := OrderedCollection new.
        self selectorsDo:[:sel| (methods includesKey: sel) ifFalse:[removals  
add: sel]].
        removals do:[:sel| self traitRemoveSelector: sel].

        "Clean out empty categories"
        oldCategories do:[:cat|
                (self organization isEmptyCategoryNamed: cat)
                        ifTrue:[self organization removeCategory: cat]].

        self isMeta ifFalse:[self class updateTraitsFrom:  
aTraitComposition].! !


Not that it bothers me... Andreas is free to do what he likes in his  
Squeak ;)

Cheers,
Adrian
_______________________________________________
Pharo-project mailing list
[email protected]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project

Reply via email to