<div dir="ltr">I've been doing a bit of poking around the image and perhaps a more succinct way of making the point is that in general, the pattern of '<an object reference> class <an instance creation selector>' usually works but is often incorrect. For example, cases of:<div><br></div><div>self class new</div><div><br></div><div>are often incorrect and should generally, but not always[1], be:</div><div><br></div><div>self species new</div><div><br></div><div>I suspect the reason this isn't a problem for most people, most of the time is that:</div><div><br></div><div>1) most of the time #species and #class return the same class</div><div><br></div><div>2) people are usually directly using instances of relatively straightforward class hierarchies</div><div><br></div><div>[1] While I'm sure there are cases, they would be the exception rather than the rule.</div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Oct 2, 2019 at 4:13 PM Phil B <<a href="mailto:pbpublist@gmail.com" target="_blank">pbpublist@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="auto"><div>Juan,<br><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Oct 2, 2019, 11:21 AM Juan Vuletich <<a href="mailto:juan@jvuletich.org" target="_blank">juan@jvuletich.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><u></u>
<div bgcolor="#ffffff">
On 10/1/2019 2:39 AM, Phil B wrote:<br><blockquote type="cite">
<div dir="ltr">
<div class="gmail_quote">
<div>The first example I ran into was in Vector3>cross:
(you can see an implementation of it here: <a href="https://github.com/pbella/Cuis-OpenGL/blob/master/3DTransform.pck.st#L2247" rel="noreferrer" target="_blank">https://github.com/pbella/Cuis-OpenGL/blob/master/3DTransform.pck.st#L2247</a>)
though pretty much any sender of #species (I have over 200
in my image) potentially applies: what you're returning
changes the definition of #species and therefore may[3]
break existing code. What's most problematic about this
change is that because it's relatively subtle, it may not be
immediately obvious in all cases what the breakage is
because existing code will kinda-sorta work: you'll get back
a class which may mostly work right up until the point that
it doesn't which might be pretty far from the sender of
#species that resulted in the now problematic instance.</div></div></div></blockquote>
I took a look at your code, and it seems to assume that #species is
a synonym for #class. I'd rather call #class, but that's not the
main issue here. <br></div></blockquote></div></div><div dir="auto"><br></div><div>No, this actually *is* one of the main issues. The 'not a collection' argument was about *what* you wanted to do. The #species argument was about *how* you were trying to do it. So even though the *what* went away, we still have the *how* which I think is important we come to agreement on. (mainly for future reference should anyone want to override #species)</div><div><br></div><div>As I understand it, #species is what one should send *instead* of #class to find the 'correct' class to use when one wants to create a new instance based on the type of an existing object. Sure, usually it will return the same thing as #class... but not always. The 'but not always' is key as they are similar, not the same. There are two main use cases off the top of my head where this is critical: 1) proxy objects 2) polymorphic hierarchies. In both cases, #species and #class will often return different classes with the difference being that #class returns the class that the existing instance *is* and #species returns the class that you should use (which may decide to instantiate a different, usually sub-, class) to create a new instance. Probably the more common use case is not sending #species to self but rather to a parameter passed in to a method but both scenarios seem equally valid to me.</div><div><br></div><div>An extreme, but not pathological example is that you might have someObject that you want to create a new instance of. However, someObject is a profiling proxy (class P) wrapped around a debugging proxy (class D) wrapped around an instance of class SomeSubtype which is a subclass of SomeType. The proxy instances P and D are runtime instrumentation and irrelevant to the object that should be created and SomeSubtype is what was determined to be the appropriate subclass to instantiate based on conditions/parameters at its instantiation time which might be different the next time an instance is created. When I send someObject #class it will return P but what I really need it to do is send #species which should return SomeType. That is my understanding of what #species should do and why it's important.</div><div><br></div><div>So I would argue that the example I provided, while trivial, was the more 'correct' way to use it. The way most people write and use Smalltalk code, it doesn't matter as #class will get you what you need. That's fine, but please don't mess with #species because for some code the distinction is vital and you will break code.</div><div dir="auto"><br></div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div bgcolor="#ffffff">
<br>
The changes I did to #species are not useful, because we need a
better solution that treats #select: (same class of elements,
possibly different number of them) and #collect: (possibly different
kind of elements, but same number of them) in a distinct way.<br></div></blockquote><div><br></div><div>The problem I had with your #species changes is that they were *wrong* per the intent of the #species method. If you had decided 'nah, I don't care... I want to treat a Color as a collection anyway', I could live with that because I would not be forced to use/treat it as one. (that said, I like that we're agreeing not to do that.) However, your #species change broke code by using a new definition inconsistent with its original intent.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div bgcolor="#ffffff">
<br>
Besides, I made Color (the motivation for that change) no longer be
a Collection, as you, Nicolas and Hernán have suggested, and just
told in a separate email.<br>
<br>
So, I removed ArrayedCollection>>#species.<br>
<br>
Thanks for caring.<br>
<br>
Cheers,<br>
<pre cols="72">--
Juan Vuletich
<a href="http://www.cuis-smalltalk.org" rel="noreferrer" target="_blank">www.cuis-smalltalk.org</a>
<a href="https://github.com/Cuis-Smalltalk/Cuis-Smalltalk-Dev" rel="noreferrer" target="_blank">https://github.com/Cuis-Smalltalk/Cuis-Smalltalk-Dev</a>
<a href="https://github.com/jvuletich" rel="noreferrer" target="_blank">https://github.com/jvuletich</a>
<a href="https://www.linkedin.com/in/juan-vuletich-75611b3" rel="noreferrer" target="_blank">https://www.linkedin.com/in/juan-vuletich-75611b3</a>
@JuanVuletich</pre></div></blockquote><div><br></div><div>Thanks,</div><div>Phil </div></div></div></div>
</div>
</blockquote></div>