<div dir="ltr"><br><br><div class="gmail_quote">On Fri, Aug 8, 2008 at 7:07 PM, Igor Stasenko <span dir="ltr">&lt;<a href="mailto:siguctua@gmail.com">siguctua@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div><div></div><div class="Wj3C7c">2008/8/9 Eliot Miranda &lt;<a href="mailto:eliot.miranda@gmail.com">eliot.miranda@gmail.com</a>&gt;:<br>
&gt;<br>
&gt;<br>
&gt; On Fri, Aug 8, 2008 at 6:09 PM, Igor Stasenko &lt;<a href="mailto:siguctua@gmail.com">siguctua@gmail.com</a>&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt; 2008/8/9 Eliot Miranda &lt;<a href="mailto:eliot.miranda@gmail.com">eliot.miranda@gmail.com</a>&gt;:<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; On Fri, Aug 8, 2008 at 5:46 PM, Igor Stasenko &lt;<a href="mailto:siguctua@gmail.com">siguctua@gmail.com</a>&gt;<br>
&gt;&gt; &gt; wrote:<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; 2008/8/9 Eliot Miranda &lt;<a href="mailto:eliot.miranda@gmail.com">eliot.miranda@gmail.com</a>&gt;:<br>
&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt; &gt; On Fri, Aug 8, 2008 at 3:53 PM, Igor Stasenko &lt;<a href="mailto:siguctua@gmail.com">siguctua@gmail.com</a>&gt;<br>
&gt;&gt; &gt;&gt; &gt; wrote:<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; Sets which not allowing contain nil as element is a point of<br>
&gt;&gt; &gt;&gt; &gt;&gt; inconvenience.<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; There are two ways how get around that:<br>
&gt;&gt; &gt;&gt; &gt;&gt; - initialize an array which contains set elements with unique object<br>
&gt;&gt; &gt;&gt; &gt;&gt; ~~<br>
&gt;&gt; &gt;&gt; &gt;&gt; nil.<br>
&gt;&gt; &gt;&gt; &gt;&gt; and fix methods which testing for an empty slots to compare against<br>
&gt;&gt; &gt;&gt; &gt;&gt; this object, not nil.<br>
&gt;&gt; &gt;&gt; &gt;&gt; This can cause a slowdown during rehashing, because VM initially<br>
&gt;&gt; &gt;&gt; &gt;&gt; creating arrays filled with nils, while we need to fill them with<br>
&gt;&gt; &gt;&gt; &gt;&gt; another object.<br>
&gt;&gt; &gt;&gt; &gt;&gt; There is also a problem with preserving it &#39;uniqueness&#39; by not<br>
&gt;&gt; &gt;&gt; &gt;&gt; giving<br>
&gt;&gt; &gt;&gt; &gt;&gt; this object outside a set.<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; - add an instVar &#39;containsNil&#39;<br>
&gt;&gt; &gt;&gt; &gt;&gt; then when set receiving &#39;add: nil&#39; , it simply sets this flag to<br>
&gt;&gt; &gt;&gt; &gt;&gt; true.<br>
&gt;&gt; &gt;&gt; &gt;&gt; modify #collect: , #do: , #remove: to be aware of flag value.<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; I find the second way is more appropriate. While it costs additional<br>
&gt;&gt; &gt;&gt; &gt;&gt; memory per Set/IdentitySet instance, it costs almost nothing in<br>
&gt;&gt; &gt;&gt; &gt;&gt; speed.<br>
&gt;&gt; &gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt;&gt; What do you think about supporting Sets to contain nils in general,<br>
&gt;&gt; &gt;&gt; &gt;&gt; and about methods how to achieve that?<br>
&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt; &gt; Here&#39;s a third approach (a variation on your 2nd approach). &nbsp;Have an<br>
&gt;&gt; &gt;&gt; &gt; instVar<br>
&gt;&gt; &gt;&gt; &gt; &#39;includesSelf&#39; and fill the array with the Set itself. &nbsp;So add a new<br>
&gt;&gt; &gt;&gt; &gt; primitive new:fillWith: (primitiveNewWithArgAndFillValue?) and use<br>
&gt;&gt; &gt;&gt; &gt; this<br>
&gt;&gt; &gt;&gt; &gt; to<br>
&gt;&gt; &gt;&gt; &gt; create the empty array filled with the Set itself. &nbsp;Check for adding<br>
&gt;&gt; &gt;&gt; &gt; the<br>
&gt;&gt; &gt;&gt; &gt; set<br>
&gt;&gt; &gt;&gt; &gt; itself, and itself being the null entry. &nbsp;The advantage over the flag<br>
&gt;&gt; &gt;&gt; &gt; for<br>
&gt;&gt; &gt;&gt; &gt; nil approach is that you kill two birds with one stone.<br>
&gt;&gt; &gt;&gt; &gt; 1. You need a unique value anyway, and the Set can nicely be its own<br>
&gt;&gt; &gt;&gt; &gt; unique<br>
&gt;&gt; &gt;&gt; &gt; value<br>
&gt;&gt; &gt;&gt; &gt; 2. recursive collections are a problem to print and with the explicit<br>
&gt;&gt; &gt;&gt; &gt; flag<br>
&gt;&gt; &gt;&gt; &gt; this becomes much easier to deal with.<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; In math domain, any set includes itself , not as element of course,<br>
&gt;&gt; &gt;&gt; but as subset :)<br>
&gt;&gt; &gt;&gt; And i don&#39;t see how this is better comparing to having &#39;containsNil&#39;<br>
&gt;&gt; &gt;&gt; ivar?<br>
&gt;&gt; &gt;&gt; You still have to test this flag in each method which deals with<br>
&gt;&gt; &gt;&gt; elements , so be it containsFoo or containsBar - no real difference.<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; One difference is the use of self for the unique object instead of<br>
&gt;&gt; &gt; another.<br>
&gt;&gt; &gt; Another difference is that recursive sets no longer fail to print,<br>
&gt;&gt; &gt; inspect,<br>
&gt;&gt; &gt; etc.<br>
&gt;&gt; &gt; I think those are real differences.<br>
&gt;&gt; &gt;<br>
&gt;&gt;<br>
&gt;&gt; Valid point.<br>
&gt;&gt;<br>
&gt;&gt; As a bytecode proofy, can you tell how much different a bytecode will be<br>
&gt;&gt; for:<br>
&gt;<br>
&gt; what&#39;s a proofy? &nbsp;;)<br>
&gt;<br>
</div></div>an expert :)<br>
<div class="Ih2E3d"><br>
&gt;&gt;<br>
&gt;&gt; obj == nil<br>
&gt;&gt; versus<br>
&gt;&gt; obj == self<br>
&gt;&gt; versus<br>
&gt;&gt; obj isNil<br>
&gt;<br>
&gt; Depends. &nbsp;In an Interpreter obj == self likely to be slightly faster than<br>
&gt; obj == nil since nil must be fetched either form the specialObjectsArray (if<br>
&gt; bytecode set has pushNl, as it does) or from the method&#39;s literal frame. &nbsp;In<br>
&gt; a JIT they&#39;re liely the same because self is a read through the frame<br>
&gt; pointer and nil is a constant embedded in the instruction stream. &nbsp;These are<br>
&gt; likely to be of similar cost.<br>
&gt; obj isNil will either be the same cost as == nil or slower depending on<br>
&gt; whether the bytecode compiler inlines it.<br>
&gt; But the difference between obj == self &amp; obj == nil/obj isNil will be in the<br>
&gt; noise.<br>
&gt; You should make the decision on convenience.<br>
&gt;&gt;<br>
&gt;&gt; what is faster/slower?<br>
&gt;<br>
&gt; anArray asSet size is faster than any of the alternatives because it is<br>
&gt; easier to thunk about ;) &nbsp;Faster thought is much more valuable than faster<br>
&gt; processing, c.f. Smalltalk programs vs C++ programs ;)<br>
&gt;<br>
<br>
</div>yes, i raised this topic exactly from this reason.<br>
What i&#39;m not sure that is this change is so badly needed.<br>
Maybe its only me who get stuck with a problem how to deal with sets<br>
where nils are meaningful and useful value.</blockquote><div><br></div><div>I&#39;ve certainly run into it before and I know colleagues have in the past. &nbsp;What&#39;s hard to tell is how much code out there is working around the limitation.&nbsp;</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><br>
<font color="#888888"><br>
--<br>
</font><div><div></div><div class="Wj3C7c">Best regards,<br>
Igor Stasenko AKA sig.<br>
<br>
</div></div></blockquote></div><br></div>