[Cuis-dev] [Ann] Serialization of BlockClosures

Phil B pbpublist at gmail.com
Wed Oct 2 16:14:32 PDT 2019


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:

self class new

are often incorrect and should generally, but not always[1], be:

self species new

I suspect the reason this isn't a problem for most people, most of the time
is that:

1) most of the time #species and #class return the same class

2) people are usually directly using instances of relatively
straightforward class hierarchies

[1] While I'm sure there are cases, they would be the exception rather than
the rule.


On Wed, Oct 2, 2019 at 4:13 PM Phil B <pbpublist at gmail.com> wrote:

> Juan,
>
> On Wed, Oct 2, 2019, 11:21 AM Juan Vuletich <juan at jvuletich.org> wrote:
>
>> On 10/1/2019 2:39 AM, Phil B wrote:
>>
>> The first example I ran into was in Vector3>cross: (you can see an
>> implementation of it here:
>> https://github.com/pbella/Cuis-OpenGL/blob/master/3DTransform.pck.st#L2247)
>> 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.
>>
>> 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.
>>
>
> 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)
>
> 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.
>
> 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.
>
> 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.
>
>
>> 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.
>>
>
> 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.
>
>
>>
>> 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.
>>
>> So, I removed ArrayedCollection>>#species.
>>
>> Thanks for caring.
>>
>> Cheers,
>>
>> --
>> Juan Vuletichwww.cuis-smalltalk.orghttps://github.com/Cuis-Smalltalk/Cuis-Smalltalk-Devhttps://github.com/jvuletichhttps://www.linkedin.com/in/juan-vuletich-75611b3
>> @JuanVuletich
>>
>>
> Thanks,
> Phil
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.cuis.st/mailman/archives/cuis-dev/attachments/20191002/4c5f2e43/attachment.htm>


More information about the Cuis-dev mailing list