[squeak-dev] IdentitySet>>collect:

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Thu Nov 27 12:07:27 UTC 2014


2014-11-27 9:21 GMT+01:00 Frank Lesser <frank-lesser at lesser-software.com>:

> hmm
> ( Set withAll: #( 1 -1 )) collect: [  : e | e abs ] a Set(1)
>
>
IMO, these snippets have no sense...
In somes cases, we will want to preserve uniqueness, in some cases we will
want to preserve the size...
#collect:as: answers to most use cases, explicitely.

Answering an Array is a bit against the current trend which is to preserve
as far as possible the collection properties when selecting/collecting.
For example, Dictionary collect: now answer a Dictionary, what it did not
in the past.
In most cases (except maybe Interval) this is possible when selecting, but
not necessarily when collecting due to restrictions on element type
(ByteArray WordArray String IdentitySet...), or due to Identity or non
weak-references properties that have absolutely no guaranty to be preserved
once transformed.
Note that #species was originally used for both selecting and collecting,
but we started to distinguish these two, that might be the reason for the
current non-uniformity of its usage.
Some collection change of species when collecting, some other just fail,
obviously because we expect aString collect: #asUppercase to answer a
String, not an Array...
In all these cases, collect:as: is a generic answer.

Anyway, a 1-to-1 mapping with something unordered is quite useless...
How are we going to map elements of the transformed collection with the
original?
We cannot iterate like this: (aSet with: anOrderedCollection do: [:a :b |
]), nor with a Stream or any sequenceable protocol on an unordered
collection.

The only guaranty you have is that the block will be evaluated once with
each item (if there is no block return or exception raised...).
Even this expectation might be questionable, I once suggested to iterate
only once per different value in a Bag, or once per run in a RunArray when
collecting/selecting...
i did not, because too many code rely on the side effects like
   | i |
   i := 0. aSet collect: [:each | i := i + 1. each transformWithRank: i].
IMO, this is bad style.

Nicolas


> -----Ursprüngliche Nachricht-----
> Von: squeak-dev-bounces at lists.squeakfoundation.org
> [mailto:squeak-dev-bounces at lists.squeakfoundation.org] Im Auftrag von Bert
> Freudenberg
> Gesendet: Donnerstag, 27. November 2014 08:57
> An: The general-purpose Squeak developers list
> Betreff: Re: [squeak-dev] IdentitySet>>collect:
>
> On 27.11.2014, at 02:23, Florin Mateoc <florin.mateoc at gmail.com> wrote:
> >
> > On 11/26/2014 7:14 PM, Levente Uzonyi wrote:
> >> Your example hides the problem of ordering - what Tobias is asking about
> - so here's another:
> >>
> >> (IdentitySet withAll: #(1 1.0)) collect: [ :each | each class ]
> >>
> >> If IdentitySet >> #collect: were returning an Array, then what would be
> the answer?
> >>
> >> { SmallInteger. Float } or { Float. SmallInteger } ?
> > snip
> >> Levente
> >
> >
> > Then why does Dictionary>>keys return an Array? Where does the order come
> from in that example?
> > Similarly, where does the order come from when you invoke collect:as: on
> a
> set with Array as an argument?
> > The answer is quite simple: it is the iteration order. collect: is part
> of
> the _iteration_ protocol.
> >
> > I agree with Frank here, for me a more important aspect of collect: is
> preserving the _mapping_ between the original
> > elements and the collected values.
> > There is no obvious mapping if there are fewer collected values than
> elements.
> >
> > Florin
>
> I agree. The order is unimportant, it's a Set after all. What *is*
> important
> is getting a collection of the same size back - by default. For other needs
> we have collect:as:.
>
> - Bert -
>
>
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20141127/e7a62be7/attachment.htm


More information about the Squeak-dev mailing list