<div dir="ltr"><div dir="ltr"><div><div>I'm assuming you're referring to my first example use case (if not, you've lost me): It's not a case of undesirable forms of polymorphism, it's a case of invalid forms of polymorphism. Just because the image/VM uses polymorphism to (usually) nicely get you to the debugger doesn't mean polymorphism is always the answer.</div><div><br></div><div>Sometimes, discontinuities in control flow (and hijacking those discontinuities) are your only way out of / around a problem and it is desirable/necessary to control when and how they occur to allow for more graceful recovery or by invoking the debugger/logging an error sooner rather than later to provide more meaningful feedback.</div></div><div><br></div><div>If one is developing a relatively straightforward application interactively in the image, sure just wait for the debugger to pop and solve the problems as they occur. That approach falls apart rather quickly when you bring background processes, FFI and networking into the mix and is a non-starter for most server-based applications. If you add to the mix sourcing arbitrary code/data from the Internet, you are now living with a qualitatively different order of pain. That's when things like #is: start looking really good vs. the alternatives.</div><div><br></div></div><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Aug 6, 2019 at 7:28 PM Andres Valloud via Cuis-dev <<a href="mailto:cuis-dev@lists.cuis.st">cuis-dev@lists.cuis.st</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">The argument seems to be that undesirable forms of polymorphism can be <br>
avoided with #is: messages--- yet the #is: messages are polymorphic <br>
themselves. Why, exactly, is the polymorphic use of #is: better than <br>
other forms of polymorphism?<br>
<br>
To me, that kind of usage reimplements by hand what the VM is working so <br>
hard to provide. The result is code that is slower (the system has more <br>
to do), and bigger (my brain has more to think about). But don't repeat <br>
yourself, once and only once, and all that. So I'd rather not.<br>
<br>
On 8/6/19 15:39, Phil B wrote:<br>
> Two main use cases off the top of my head:<br>
> <br>
> 1) Sometimes I'm doing an assert: (x is #Foo) where I need to check <br>
> behavior, not type, in the assertion. (#respondsTo: is too granular)<br>
> <br>
> 2) Dynamic dispatch. A recent example that comes to mind is a clipboard <br>
> object handler where I had a dynamic dispatcher that is generated <br>
> dynamically at runtime based on what packages are loaded when it is called.<br>
> <br>
> Polymorphism is a great tool, but it's not always the right tool.<br>
> <br>
> <br>
> On Tue, Aug 6, 2019, 5:55 PM Andres Valloud via Cuis-dev <br>
> <<a href="mailto:cuis-dev@lists.cuis.st" target="_blank">cuis-dev@lists.cuis.st</a> <mailto:<a href="mailto:cuis-dev@lists.cuis.st" target="_blank">cuis-dev@lists.cuis.st</a>>> wrote:<br>
> <br>
> If one is willing to implement #is: and friends so that one can write<br>
> <br>
> (x is: #Blah) ifTrue: [x doSomething]<br>
> <br>
> then why not just write the following?<br>
> <br>
> x doSomethingIfBlah<br>
> <br>
> It's essentially the same number of methods, and if too many of those<br>
> start accumulating in Object then you know there's a design problem<br>
> that<br>
> should be fixed rather than accommodated.<br>
> <br>
> Also, it's way faster because now there are fewer message sends, and<br>
> the<br>
> code is delegating the class / protocol checks to the VM (which was<br>
> there to provide that functionality in the first place).<br>
> <br>
> On 8/6/19 14:08, Phil B wrote:<br>
> > I've always seen the value as being two-fold:<br>
> ><br>
> > 1) To avoid needing to implement N #is* methods on Object (and<br>
> there's a<br>
> > lot more of this out there than just what the base image<br>
> implements and<br>
> > uses)<br>
> ><br>
> > 2) As a mechanism to test for *protocol* compliance rather than<br>
> *class*<br>
> > membership of an object. One may or may not agree with this<br>
> > interpretation, but lacking a definition that said otherwise, I<br>
> decided<br>
> > it meant this as well 😀<br>
> ><br>
> > While implementations in the base image tend to have a 1:1<br>
> relationship<br>
> > with a particular class, it is not required. For example, I have a<br>
> > number of classes that return true for #is: which aren't actually<br>
> > subclasses of the thing they return true for but do behave as if<br>
> they<br>
> > were. I don't care so much if a given object isKindOf: Morph, but<br>
> > rather if it behaves as one.<br>
> ><br>
> > There was a time when I tried to make the second use case more<br>
> explicit<br>
> > but there didn't seem to be a interest from others. So I may be the<br>
> > only person who makes use of the second use case today. If so and 1<br>
> > isn't seen as a worthwhile reason to stick with this approach, I<br>
> can do<br>
> > this another way.<br>
> ><br>
> > On Tue, Aug 6, 2019, 3:21 PM Andres Valloud via Cuis-dev<br>
> > <<a href="mailto:cuis-dev@lists.cuis.st" target="_blank">cuis-dev@lists.cuis.st</a> <mailto:<a href="mailto:cuis-dev@lists.cuis.st" target="_blank">cuis-dev@lists.cuis.st</a>><br>
> <mailto:<a href="mailto:cuis-dev@lists.cuis.st" target="_blank">cuis-dev@lists.cuis.st</a> <mailto:<a href="mailto:cuis-dev@lists.cuis.st" target="_blank">cuis-dev@lists.cuis.st</a>>>> wrote:<br>
> ><br>
> > So it looks like the #is: methods are there to implement the<br>
> > functionality of #isXYZ messages with half the methods, which<br>
> in turn<br>
> > are there presumably to avoid having to send class or<br>
> #isKindOf:. But<br>
> > one way or another, they are still class checks done in the<br>
> language,<br>
> > when the system already provides fast and invisible class<br>
> checking in<br>
> > every message send.<br>
> ><br>
> > In an old Cuis image that I have handy right now, there are 30<br>
> > implementors of #is:. There are 120 senders, but<br>
> (essentially) 30 of<br>
> > those are the implementors just mentioned. So, 90 senders for 30<br>
> > methods, a use factor of 3. A brief look suggests a<br>
> histogram, which<br>
> > yields the following arguments for #is: (excluding the<br>
> implementors<br>
> > themselves).<br>
> ><br>
> > #(#Text #Color #Morph #Morph #Text #Morph #Form #Text #Morph<br>
> #Form<br>
> > #Text<br>
> > #Text #Text #Form #Morph #Text #PluggableButtonMorph<br>
> #CompiledMethod<br>
> > #Morph #Color #Color #ColorForm #CompiledMethod #Stream #Text<br>
> #Stream<br>
> > #Morph #DateAndTime #DateAndTime #DateAndTime #DateAndTime<br>
> #DateAndTime<br>
> > #Text #Array #HandMorph #InnerTextMorph #InnerTextMorph<br>
> #SystemWindow<br>
> > #SystemWindow #HandMorph #MessageSend #Color #Text #ScrollPane<br>
> > #CompiledMethod #Text #HandMorph #MenuItemMorph #MenuItemMorph<br>
> > #MenuItemMorph #MenuItemMorph #UpdatingMenuItemMorph<br>
> > #UpdatingMenuItemMorph #LayoutMorph #HandMorph<br>
> #CompiledMethod #Stream<br>
> > #Stream #Text #HandMorph #SystemWindow #HandMorph<br>
> #MorphicEvent #Morph<br>
> > #HaloMorph #Stream #Text #Text #HaloMorph #SystemWindow #Taskbar<br>
> > #SystemWindow #SystemWindow #MessageSend #refusingToAccept #Text<br>
> > #Rectangle #Rectangle #Rectangle #Rectangle #Rectangle #Text<br>
> > #hasTextProvider #hasTextProvider #Stream #Text #Text #Text<br>
> > #CompiledMethod #SystemWindow #SystemWindow #PluggableListMorph<br>
> > #SystemWindow #SystemWindow #Taskbar #Text #Morph #Text #Text<br>
> #Text<br>
> > #DateAndTime #DateAndTime #DateAndTime #DateAndTime #DateAndTime<br>
> > #UpdatingMenuItemMorph #ColorForm #MessageSend #MessageSend<br>
> #Morph<br>
> > #Morph)<br>
> ><br>
> > As a set, this collection has a size of 25 (so already this<br>
> suggests<br>
> > dead code is present). Further, as an actual histogram, we<br>
> see this:<br>
> ><br>
> > #Text -> 23<br>
> > #Morph -> 11<br>
> > #DateAndTime -> 10<br>
> > #SystemWindow -> 10<br>
> > #Stream -> 6<br>
> > #HandMorph -> 6<br>
> > #Rectangle -> 5<br>
> > #CompiledMethod -> 5<br>
> > #MessageSend -> 4<br>
> > #Color -> 4<br>
> > #MenuItemMorph -> 4<br>
> > #UpdatingMenuItemMorph -> 3<br>
> > #Form -> 3<br>
> > #hasTextProvider -> 2<br>
> > #HaloMorph -> 2<br>
> > #Taskbar -> 2<br>
> > #ColorForm -> 2<br>
> > #InnerTextMorph -> 2<br>
> > #PluggableButtonMorph -> 1<br>
> > #LayoutMorph -> 1<br>
> > #Array -> 1<br>
> > #refusingToAccept -> 1<br>
> > #PluggableListMorph -> 1<br>
> > #ScrollPane -> 1<br>
> > #MorphicEvent -> 1<br>
> ><br>
> > which suggests there is something going on, design-wise, with<br>
> the top<br>
> > 20% because together they account for much more than 50% of<br>
> the usage.<br>
> ><br>
> > So, even though as syntax I would find it just fine, I wonder<br>
> if this<br>
> > improvement is optimizing the highest priority problem.<br>
> ><br>
> > What has been the evolution / usage of this feature over<br>
> time? Where<br>
> > should it go from here?<br>
> ><br>
> > On 8/6/19 04:54, Juan Vuletich via Cuis-dev wrote:<br>
> > > Hi Folks,<br>
> > ><br>
> > > One thing I don't like about the #is: message is that being a<br>
> > keyword,<br>
> > > it usually requires parenthesis. Today I realized we can<br>
> use #?<br>
> > instead.<br>
> > > So, we could write:<br>
> > ><br>
> > > aForm ? #GrayForm ifTrue: [ self doSomething ].<br>
> > ><br>
> > > instead of<br>
> > ><br>
> > > (aForm is: #GrayForm) ifTrue: [ self doSomething ].<br>
> > ><br>
> > > Do you like it? What do you prefer, #is: or #? ? Reasons for<br>
> > adopting or<br>
> > > not adopting it?<br>
> > ><br>
> > > Thanks,<br>
> > ><br>
> > --<br>
> > Cuis-dev mailing list<br>
> > <a href="mailto:Cuis-dev@lists.cuis.st" target="_blank">Cuis-dev@lists.cuis.st</a> <mailto:<a href="mailto:Cuis-dev@lists.cuis.st" target="_blank">Cuis-dev@lists.cuis.st</a>><br>
> <mailto:<a href="mailto:Cuis-dev@lists.cuis.st" target="_blank">Cuis-dev@lists.cuis.st</a> <mailto:<a href="mailto:Cuis-dev@lists.cuis.st" target="_blank">Cuis-dev@lists.cuis.st</a>>><br>
> > <a href="https://lists.cuis.st/mailman/listinfo/cuis-dev" rel="noreferrer" target="_blank">https://lists.cuis.st/mailman/listinfo/cuis-dev</a><br>
> ><br>
> -- <br>
> Cuis-dev mailing list<br>
> <a href="mailto:Cuis-dev@lists.cuis.st" target="_blank">Cuis-dev@lists.cuis.st</a> <mailto:<a href="mailto:Cuis-dev@lists.cuis.st" target="_blank">Cuis-dev@lists.cuis.st</a>><br>
> <a href="https://lists.cuis.st/mailman/listinfo/cuis-dev" rel="noreferrer" target="_blank">https://lists.cuis.st/mailman/listinfo/cuis-dev</a><br>
> <br>
-- <br>
Cuis-dev mailing list<br>
<a href="mailto:Cuis-dev@lists.cuis.st" target="_blank">Cuis-dev@lists.cuis.st</a><br>
<a href="https://lists.cuis.st/mailman/listinfo/cuis-dev" rel="noreferrer" target="_blank">https://lists.cuis.st/mailman/listinfo/cuis-dev</a><br>
</blockquote></div></div>