<div dir="auto"><div>Two main use cases off the top of my head:<div dir="auto"><br></div><div dir="auto">1) Sometimes I'm doing an assert: (x is #Foo) where I need to check behavior, not type, in the assertion. (#respondsTo: is too granular)</div><div dir="auto"><br></div><div dir="auto">2) Dynamic dispatch. A recent example that comes to mind is a clipboard object handler where I had a dynamic dispatcher that is generated dynamically at runtime based on what packages are loaded when it is called.</div><div dir="auto"><br></div>Polymorphism is a great tool, but it's not always the right tool.</div><div dir="auto"><br><br><div class="gmail_quote" dir="auto"><div dir="ltr" class="gmail_attr">On Tue, Aug 6, 2019, 5:55 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:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">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 that <br>
should be fixed rather than accommodated.<br>
<br>
Also, it's way faster because now there are fewer message sends, and 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 there's a <br>
> lot more of this out there than just what the base image implements and <br>
> uses)<br>
> <br>
> 2) As a mechanism to test for *protocol* compliance rather than *class* <br>
> membership of an object. One may or may not agree with this <br>
> interpretation, but lacking a definition that said otherwise, I decided <br>
> it meant this as well 😀<br>
> <br>
> While implementations in the base image tend to have a 1:1 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 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 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 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" rel="noreferrer">cuis-dev@lists.cuis.st</a> <mailto:<a href="mailto:cuis-dev@lists.cuis.st" target="_blank" rel="noreferrer">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 in turn<br>
> are there presumably to avoid having to send class or #isKindOf:. But<br>
> one way or another, they are still class checks done in the language,<br>
> when the system already provides fast and invisible class 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 (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 histogram, which<br>
> yields the following arguments for #is: (excluding the implementors<br>
> themselves).<br>
> <br>
> #(#Text #Color #Morph #Morph #Text #Morph #Form #Text #Morph #Form<br>
> #Text<br>
> #Text #Text #Form #Morph #Text #PluggableButtonMorph #CompiledMethod<br>
> #Morph #Color #Color #ColorForm #CompiledMethod #Stream #Text #Stream<br>
> #Morph #DateAndTime #DateAndTime #DateAndTime #DateAndTime #DateAndTime<br>
> #Text #Array #HandMorph #InnerTextMorph #InnerTextMorph #SystemWindow<br>
> #SystemWindow #HandMorph #MessageSend #Color #Text #ScrollPane<br>
> #CompiledMethod #Text #HandMorph #MenuItemMorph #MenuItemMorph<br>
> #MenuItemMorph #MenuItemMorph #UpdatingMenuItemMorph<br>
> #UpdatingMenuItemMorph #LayoutMorph #HandMorph #CompiledMethod #Stream<br>
> #Stream #Text #HandMorph #SystemWindow #HandMorph #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 #Text<br>
> #DateAndTime #DateAndTime #DateAndTime #DateAndTime #DateAndTime<br>
> #UpdatingMenuItemMorph #ColorForm #MessageSend #MessageSend #Morph<br>
> #Morph)<br>
> <br>
> As a set, this collection has a size of 25 (so already this suggests<br>
> dead code is present). Further, as an actual histogram, we 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 the top<br>
> 20% because together they account for much more than 50% of the usage.<br>
> <br>
> So, even though as syntax I would find it just fine, I wonder if this<br>
> improvement is optimizing the highest priority problem.<br>
> <br>
> What has been the evolution / usage of this feature over 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 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" rel="noreferrer">Cuis-dev@lists.cuis.st</a> <mailto:<a href="mailto:Cuis-dev@lists.cuis.st" target="_blank" rel="noreferrer">Cuis-dev@lists.cuis.st</a>><br>
> <a href="https://lists.cuis.st/mailman/listinfo/cuis-dev" rel="noreferrer 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" rel="noreferrer">Cuis-dev@lists.cuis.st</a><br>
<a href="https://lists.cuis.st/mailman/listinfo/cuis-dev" rel="noreferrer noreferrer" target="_blank">https://lists.cuis.st/mailman/listinfo/cuis-dev</a><br>
</blockquote></div></div></div>