On Sat, Nov 29, 2014 at 12:26 PM, Florin Mateoc florin.mateoc@gmail.com wrote:
On 11/29/2014 9:55 AM, Levente Uzonyi wrote:
On Fri, 28 Nov 2014, tim Rowledge wrote:
On 28-11-2014, at 6:05 PM, Levente Uzonyi leves@elte.hu wrote:
I think the conclusion was that it's better to leave the method as it is, because there's no better way to do it.
There’s *always* a better way to do it. Somebody just has to think about it the right way.
There are too many factors for a better solution to exist. Let's say we change the method to return a Bag. Some will say it's better that way, because the resulting collection has the same size as the original. And some people will say that you broke their code, because the following will return false instead of true:
| s t | s := #(1 2 3) asSet. t := s collect: [ :each | each ]. s = t
IMHO the best solution is still to replace sends of #collect: with #collect:as:, but it's a lot of work.
Levente
I don't understand why anybody would think s should be equal to t in this example. collect:, or map as it is called in other languages, maps the elements in the receiver collection, to elements in the result, based on the mapping function provided as a block argument.
I've never regarded collect as a mapping function, only a transformation function. If I want a map of the original to the transformed, it doesn't need to be built into the collect: method itself to do that:
#(1 2 3) collect: [ : each | each -> each asWords ].
There, you have a mapping without needing to change collect:.
Conceptually, collect: is closer to returning a keyedCollection (which is also called a map), where the keys are the elements and the values are their mappings. If we see it this way, it is obvious that the order of the original elements is irrelevant, it is also obvious that the number of mapped values is/has to be the same as the number of elements (keys), and it is also obvious that the kind (or species) of collection holding the original elements (keys) is also irrelevant to the kind of collection holding the values. That's why always returning say an orderedCollection is fine, as long as we can map the collected values back to the original elements - even using a (long-term unstable) iteration order. When the original collection is a sequenceableCollection, we can shortcut all this by just relying on the indexes, which index both the original elements and their mappings. But that is not because the original order is itself important for the collect operation.
Perhaps we need an #asDictionary method to implement the "mapping" use-case. As far as #collect:, however, I find myself agreeing with Levente. #collect: is simply too entrenched to change on a whim. It appears that #collect:as: can address a variety of additional use-cases..