<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">2014-11-29 3:05 GMT+01:00 Levente Uzonyi <span dir="ltr">&lt;<a href="mailto:leves@elte.hu" target="_blank">leves@elte.hu</a>&gt;</span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">The problem with changing #species is that it&#39;s overused. There are at least three different things it&#39;s used for in the Collection hierarchy:<br>
- the class of the object returned by #collect: (Set&#39;s subclasses are the exception since 2000 or so, except for WeakSet, but that&#39;s really strange, and should revisited)<br>
- the class of the object returned by #select: and friends<br>
- the class used for comparison of collections<br>
<br>
HashedCollection &gt;&gt; #select: uses #species. Changing IdentitySet <br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
#species to return a Set would break #select:, because a ~~ b doesn&#39;t <br>
</blockquote></blockquote>
imply a ~= b. IdentitySet is the optimal class for the return value of IdentitySet &gt;&gt; #select:, because it&#39;s guaranteed to be able to hold all selected values. I think the same applies to all other kind of sets (and collections, because #select: is simply reducing the number of elements).<br>
<br>
This is not the first time this discussion comes up. There was one in 2003[1], but the thread is hard to follow. And there was one in 2009[2].<br>
I think the conclusion was that it&#39;s better to leave the method as it is, because there&#39;s no better way to do it.<br>
Sure, we could use #species in #collect:, but it would break quite a lot of stuff. For example:<br>
<br>
| k |<br>
k := KeyedSet keyBlock: [ :each | each first ].<br>
k add: #[1]; add: #[2].<br>
k collect: [ :each | each size ]<br>
<br>
Currently this snippet returns &quot;a Set(1)&quot;. Using #species in #collect: (via #copyEmpty) one would get an error, because SmallInteger does not understand #first. Changing the #species of KeyedSet would break #select:.<br>
<br></blockquote><div><br></div><div>IMO select: should NOT use species, because most of the time we can select: in same class (but maybe in case of Interval).<br> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
So IMHO when you #collect: from a set, you should always use #collect:as:. Here is a (partial) list of methods which send #collect: to a Set:<br>
<br>
Categorizer &gt;&gt; #changeFromCategorySpecs:<br>
ClassFactoryForTestCase &gt;&gt; #createdClassNames<br>
Dictionary &gt;&gt; #unreferencedKeys<br>
MCDependencySorterTest &gt;&gt; #assertItems:orderAs:<u></u>withRequired:toLoad:<u></u>extraProvisions:<br>
MessageNode &gt;&gt; #analyseTempsWithin:rootNode:<u></u>assignmentPools:<br>
MethodNode &gt;&gt; #<u></u>referencedValuesWithinBlockExt<u></u>ent:<br>
SetTest &gt;&gt; #testCollect<br>
SetWithNilTest &gt;&gt; #runSetWithNilTestOf:<br>
<br>
There are probably many more, but we should fix all of them. A static analyzer could help a lot.<br>
<br>
Levente<br>
<br>
[1] <a href="http://lists.squeakfoundation.org/pipermail/squeak-dev/2003-February/052659.html" target="_blank">http://lists.squeakfoundation.<u></u>org/pipermail/squeak-dev/2003-<u></u>February/052659.html</a><br>
[2] <a href="http://lists.squeakfoundation.org/pipermail/squeak-dev/2009-November/141016.html" target="_blank">http://lists.squeakfoundation.<u></u>org/pipermail/squeak-dev/2009-<u></u>November/141016.html</a><div class="HOEnZb"><div class="h5"><br>
<br>
<br>
<br>
On Wed, 26 Nov 2014, David T. Lewis wrote:<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
It seems to me that Object&gt;&gt;species is intended to handle this sort of issue.<br>
<br>
For IdentitySet, it answers what Eliot was expecting:<br>
<br>
  IdentitySet new species ==&gt; IdentitySet<br>
  Set new species ==&gt; Set<br>
<br>
However, IdentitySet&gt;&gt;collect: does not make use of this, and it answers<br>
a Set for the reasons that Levente explained.<br>
<br>
Answering an Array or and OrderedCollection would not really make sense,<br>
because sets are unordered collections (but Bag might be better).<br>
<br>
Shouldn&#39;t we have an implementation of IdentitySet&gt;&gt;species that answers<br>
Set (or Bag), with a method comment explaining why this is the case, and<br>
with all of the collection methods using #species to answer the right<br>
kind of result?<br>
<br>
I note that IdentitySet&gt;&gt;collect: answers a Set, but IdentitySet&gt;select:<br>
sends #species and therefore answers an IdentitySet.<br>
<br>
So I think that if we want the #species of an IdentitySet to be a Set,<br>
then we should make it so, and give it a method comment to explain the<br>
rationale. And the #collect: and #select: methods should both answer a<br>
result of that #species.<br>
<br>
Dave<br>
<br>
<br>
On Thu, Nov 27, 2014 at 01:14:30AM +0100, Levente Uzonyi wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Your example hides the problem of ordering - what Tobias is asking about -<br>
so here&#39;s another:<br>
<br>
(IdentitySet withAll: #(1 1.0)) collect: [ :each | each class ]<br>
<br>
If IdentitySet &gt;&gt; #collect: were returning an Array, then what would be the<br>
answer?<br>
<br>
{ SmallInteger. Float } or { Float. SmallInteger } ?<br>
<br>
If you really want to have the resulting collection have the same size,<br>
but avoid the problem with ordering, then what you really need is a Bag.<br>
Luckily you can have whatever you want (as long as it makes sense):<br>
<br>
(IdentitySet withAll: #(1 1.0)) collect: [ :each | each asInteger ] as: Set.<br>
&quot;==&gt; a Set(1)&quot;<br>
(IdentitySet withAll: #(1 1.0)) collect: [ :each | each asInteger ] as:<br>
IdentitySet.<br>
&quot;==&gt; an IdentitySet(1)&quot;<br>
(IdentitySet withAll: #(1 1.0)) collect: [ :each | each asInteger ] as:<br>
Array.<br>
&quot;==&gt; #(1 1)&quot;<br>
(IdentitySet withAll: #(1 1.0)) collect: [ :each | each asInteger ] as:<br>
OrderedCollection.<br>
&quot;==&gt; an OrderedCollection(1 1).&quot;<br>
(IdentitySet withAll: #(1 1.0)) collect: [ :each | each asInteger ] as: Bag.<br>
&quot;==&gt; a Bag(1 1)&quot;<br>
(IdentitySet withAll: #(1 1.0)) collect: [ :each | each asInteger ] as:<br>
IdentityBag.<br>
&quot;==&gt; an IdentityBag(1 1)&quot;<br>
(IdentitySet withAll: #(1 1.0)) collect: [ :each | each asInteger ] as:<br>
Heap.<br>
&quot;==&gt; a Heap(1 1)&quot;<br>
<br>
Levente<br>
<br>
On Thu, 27 Nov 2014, Frank Lesser wrote:<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hi Tobias,<br>
agree, a problem of &quot;OrderedCollection&quot;<br>
not to break a lot of other things we could return an Array.<br>
but for me collecting has priority.<br>
Frank<br>
<br>
-----Urspr?ngliche Nachricht-----<br>
Von: <a href="mailto:squeak-dev-bounces@lists.squeakfoundation.org" target="_blank">squeak-dev-bounces@lists.<u></u>squeakfoundation.org</a><br>
[mailto:<a href="mailto:squeak-dev-bounces@lists.squeakfoundation.org" target="_blank">squeak-dev-bounces@<u></u>lists.squeakfoundation.org</a>] Im Auftrag von<br>
Tobias<br>
Pape<br>
Gesendet: Donnerstag, 27. November 2014 00:48<br>
An: The general-purpose Squeak developers list<br>
Betreff: Re: [squeak-dev] IdentitySet&gt;&gt;collect:<br>
<br>
<br>
On 27.11.2014, at 00:34, Frank Lesser &lt;<a href="mailto:frank-lesser@lesser-software.com" target="_blank">frank-lesser@lesser-software.<u></u>com</a>&gt;<br>
wrote:<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
hmm, not convinced<br>
<br>
(IdentitySet withAll: #(1 1.0)) collect: [:e| e asInteger ]<br>
OrderedCollection(1 1 )<br>
<br>
in LSWVST ( one-to-one ), you collect results of evaluating a block on<br>
objects.<br>
<br>
Frank<br>
maybe I am wrong ...<br>
</blockquote>
<br>
Where would the order come from for that _Ordered_Collection?<br>
<br>
Best<br>
        -Tobias<br>
<br>
</blockquote></blockquote>
<br>
<br>
</blockquote>
<br>
</div></div></blockquote></div><br></div></div>