[squeak-dev] Re: Some questions about new traits (Crismas edition) ; )

Igor Stasenko siguctua at gmail.com
Mon Dec 28 17:09:15 UTC 2009


2009/12/28 Andreas Raab <andreas.raab at gmx.de>:
> Igor Stasenko wrote:
>>
>> :) The Behavior protocol is insane by itself. I'm not sure that
>> removing composition from it, will make it less bloated or less
>> complex.
>
> The problem with the behavior protocol is that has become bloated:
>
> {Behavior. ClassDescription. Class. Metaclass}
>        collect:[:each| each -> each selectors size].
>
> Version      Behavior   ClassDescription    Class Metaclass Total
> 2.3             116             86             45     29     276
> 3.6             165            122             68     42     397
> 3.10            241            138             89     50     518
>
> Note that although we've doubled the number of methods since 2.3 you only
> get north of 1000 methods when you add traits to it. Individually, at a 150
> methods or so, Behavior and ClassDescription are quite manageable. Wait
> until I'm through with a round of cleanup and I think I can give the 3.6
> version a run for its money - I'm optimistic that something around 50-100
> methods should be removable after installing NanoTraits.
>
i can help you with that:


#nextQuotePosIn: sourceString startingFrom: commentStart
#commentsIn: sourceString
#commentsAt:  selector

3 methods which has nothing to do with behavior, but purely is a text
manipulation stuff.
Btw, who said that behavior can access method's source code by any means?
Should we also implement regexp here?

#precodeCommentOrInheritedCommentFor: selector
#firstPrecodeCommentFor:
same as above..


#nonObsoleteClass
#obsolete
#canZapMethodDictionary
#obsoleteSubclasses
#removeAllObsoleteSubclasses
#removeObsoleteSubclass:
#zapAllMethods

introducing a concept , which does not belongs there. The "obsolete"
notion belongs to higher level domain, and must be handled there. i.e.
Smalltalk isObsoleteClass: someBehavior , or whatever.. but not in Behavior.

#printHierarchy
- in how many places this method is useful?  I found just two.

#removeSelector: / #removeSelectorSilently:
- a work around of a limitation of other unrelated framework - system
change notification..
  instead of making a lots of #blahblahSilently methods.. why not add just one:
self silentlyDo: [ do anything you want ] ??


#rootStubInImageSegment: imageSegment
- dad, i seen a footprints of a snow man!

#selectSubclasses: aBlock
#selectSuperclasses: aBlock

self all[Sub/Super]classes select: [:cls | cls removeSelector:
#selectSubclasses:; removeSelector: #selectSuperclasses: ]

#sourceCodeAt: / #sourceMethodAt:
- there should be only one

#spaceUsed
 - why behavior should be responsible for that? How about
#numberOfStarsInGalaxy?

#standardMethodHeaderFor: aSelector
another string manipulation horror

#subclassInstVarNames
have no uses and never gonna be

#supermostPrecodeCommentFor: selector
a key part of Behavior functionality

#thoroughWhichSelectorsReferTo:
- why it have to serve as a stockpile of various obscure reflection features?
Can i have mine #oneThatRefersTo: butNotTo: andNotUsingClass:  ?


Note, I am intentionally not listed methods which related to traits.


>> The nature of problem lies elsewhere (in same place where lies the
>> problem of bloat in Object  and Morph protocols)
>> - same object can play many independent roles depending on use scenario.
>> Grouping the methods per role is, what i think traits could help with.
>> If method #foo and #bar defined in same trait, then
>> they serve for a single role (unless trait developer is a dumbass ;).
>> And in case if i would want to change the role, or remove it, i will
>> know exactly, what methods i may need to touch & revise, instead of
>> staring at 1000 methods in a single class and wondering how they
>> depend from each other.
>> I sense it, as a method's category, living on its own, without binding
>> to concrete class, not as a way to introduce MI.
>
> I understand what you're trying to achieve here but one must be wondering
> why you think this would work any better with traits than with categories
> (which we have and use for this purpose).
>
Because i can use trait in multiple places (do not mix with multiple
traits in one place ;) ).
But hardly i can do its easily for category.


>> I look on it strictly from practical perspective, not academic or
>> experiment. People usually, can't keep too much things at once in some
>> context.. 10, 20 , 30 methods... Getting over that, you soon start
>> spending time revisiting same places again and again to 'refresh' your
>> mind-cache.
>
> Certainly correct, and having a solution for that problem would be helpful.
> But I'm not sure how what you're proposing would help with that - you'd
> still have all the methods in class Object.
>
Yup.

>> A most useful aspect of Traits, as to me, is being able to define a
>> clean, standalone interface (role), irrespectively to any
>> (single/multiple) inheritance models and
>> even to smalltalk class/behavior model.
>
> But what does that defining that interface help with? And what effect has
> the multiplication of entities on other parts of the system?
>
> The way it's been used so far results in situations like seeing *seven*
> implementors of addSelectorSilently:withMethod: when there are only two, it
> results in having *three* additional variants of

We should have better tool support to show only real implementors
instead of derivatives.

> addSelectorSilently:withMethod: (methodDictAddSelectorSilently:,
> basicAddSelectorSilently:, pureAddSelectorSilently:) when there is no need
> for any and more. This is classic MI madness.
>
I don't know.. As to me, its just madness, without 'MI' prefix.

>> I've implemented own version of prototypes, and use traits to fill
>> prototypes with methods. I found that they naturally complement each
>> other in squeak environment,
>> because i can use standard dev tools for designing my proto behaviors
>> using traits, which then i can use. I even want to add a dependency
>> support to it, so
>> if you changing the trait method, all prototypes with that trait will
>> be updated accordingly.
>
> I can see how that would work better than in a system like Squeak, mostly
> because you're never going to look at the prototype's class, so you're never
> going to have to deal with its full complexity. However, I can't help but
> wonder how this works if traits require state, or if traits have conflicts.
>
It works, because in prototypes you can add/remove state dynamically &
lazily, which means that trait can define all potentially required
state
without the need of declaring it elsewhere.

> Cheers,
>  - Andreas
>
>



-- 
Best regards,
Igor Stasenko AKA sig.



More information about the Squeak-dev mailing list