<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Additionally, in the Collection hierarchy, #species is used for
#select: and #collect: as I said before. In the base image, all the
classes that redefine #species are Collections. And they redefine it
essentially to make #select: and #collect: answer a reasonable
result, for example for <br>
<br>
'Hello' collect: [ :a | a numericValue ].<br>
<br>
(1 to: 20) select: [ :a | a isPrime ].<br>
<br>
In those cases (the only ones where #species and #class differ in
the base image), the objective is _not_ to recreate the receiver.<br>
<br>
Speaking of "original intent", the comment at Object>>species
(no timestamp, I guess that comes from Squeak 1.1, or maybe
Smalltalk-80, definitely not written by me) talks about collections,
and literally says "Species and class are not always the same. For
example, the species of Interval is Array.". So it seems that
#species tries to be too many different things at once...<br>
<br>
On 10/2/2019 8:14 PM, Phil B wrote:
<blockquote
cite="mid:CAMJMOej7AtCtJZa4bn5WM2TnuwS6qn6Oz=8k0Ui9S+Zwxhp06w@mail.gmail.com"
type="cite">
<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 moz-do-not-send="true"
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 moz-do-not-send="true"
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;">
<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
moz-do-not-send="true"
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 moz-do-not-send="true" href="http://www.cuis-smalltalk.org" rel="noreferrer" target="_blank">www.cuis-smalltalk.org</a>
<a moz-do-not-send="true" href="https://github.com/Cuis-Smalltalk/Cuis-Smalltalk-Dev" rel="noreferrer" target="_blank">https://github.com/Cuis-Smalltalk/Cuis-Smalltalk-Dev</a>
<a moz-do-not-send="true" href="https://github.com/jvuletich" rel="noreferrer" target="_blank">https://github.com/jvuletich</a>
<a moz-do-not-send="true" 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>
</blockquote>
<br>
<br>
<pre class="moz-signature" cols="72">--
Juan Vuletich
<a class="moz-txt-link-abbreviated" href="http://www.cuis-smalltalk.org">www.cuis-smalltalk.org</a>
<a class="moz-txt-link-freetext" href="https://github.com/Cuis-Smalltalk/Cuis-Smalltalk-Dev">https://github.com/Cuis-Smalltalk/Cuis-Smalltalk-Dev</a>
<a class="moz-txt-link-freetext" href="https://github.com/jvuletich">https://github.com/jvuletich</a>
<a class="moz-txt-link-freetext" href="https://www.linkedin.com/in/juan-vuletich-75611b3">https://www.linkedin.com/in/juan-vuletich-75611b3</a>
@JuanVuletich</pre>
</body>
</html>