The class and metaclass system of Smalltalk is already at the limit of complexity that I can handle. Traits make this existing model even more complicated. Even with support from a trait aware browser I find traits extermely hard to use. To me the most important thing is that at all points in time I know exactly what changes when I compile a method. This is absolutely not clear when using traits.
I find your statements a bit rude.
I am not saying that you should not use them. I am just trying to explain why I am not using them myself.
I'm writing a trait to get magritte-aware xml output without having to always inherit from a top class or to copy and paste all the time the same code in my classes.
I would use delegation for that. Both, Pier and Magritte use that pattern too.
As Paolo suggested the problem can be simply solved by introducing an Iterable superclass to Collection and Stream.
I do not see how his solution will offer a faster implementation
Evaluating ((aCollection select: [ :e | ... ]) collect: [ :e | ... ]) iterates twice over aCollection, while ((aCollection readStream select: [ :e | ... ]) collect: [ :e | ... ]) contents will iterate only once. Furthermore the second approach allows any combination of any of the enumeration methods, not just a few predefined ones. Also the implementation is less error prone, because it just uses the standard methods on collection and stream.
Now you might say that this only works if I am not inheriting from some other important class. True, an Iterable-trait would avoid that problem. However, adding such a trait to an existing hierarchy looks extremely scary to me. It potentially pollutes an existing protocol with existing code that is most likely unrelated (or maybe it already contains some iterator code for something else).
like what collect: select: do: reject: inject:into: ?
What if you want to iterate forward and backward over a collection? What if you have multiple things in your model object that you want to iterate over? Would you add several iterable traits and prefix all selectors? aSystem do: ... aSystem reverseDo: ... aSystem itemsDo: ... Or rather use delegation? aSystem iterator do: ... aSystem reverseIterator do: ... aSystem itemsIterator do: ... I find the second solution much nicer because it extracts the strategy how to iterate over something to a separate object. In about any model there are multiple collections involved and multiple ways of iterating through these objects, embedding the iterators directly into the container seems wrong to me.
I think that you should also have a look at what other people are doing.
All I am saying is that collection iteration is one of the few things that Smalltalk got wrong. Cheers, Lukas -- Lukas Renggli http://www.lukas-renggli.ch