[Cuis-dev] Poll: ? instead of is: ?

John Pfersich jpfersich at gmail.com
Tue Aug 6 18:15:19 PDT 2019


+1

/————————————————————/
For encrypted mail use jgpfersich at protonmail.com
Get a free account at ProtonMail.com
Web: www.objectnets.net and www.objectnets.org

> On Aug 6, 2019, at 15:39, Phil B via Cuis-dev <cuis-dev at lists.cuis.st> wrote:
> 
> Two main use cases off the top of my head:
> 
> 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)
> 
> 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.
> 
> Polymorphism is a great tool, but it's not always the right tool.
> 
> 
>> On Tue, Aug 6, 2019, 5:55 PM Andres Valloud via Cuis-dev <cuis-dev at lists.cuis.st> wrote:
>> If one is willing to implement #is: and friends so that one can write
>> 
>>         (x is: #Blah) ifTrue: [x doSomething]
>> 
>> then why not just write the following?
>> 
>>         x doSomethingIfBlah
>> 
>> It's essentially the same number of methods, and if too many of those 
>> start accumulating in Object then you know there's a design problem that 
>> should be fixed rather than accommodated.
>> 
>> Also, it's way faster because now there are fewer message sends, and the 
>> code is delegating the class / protocol checks to the VM (which was 
>> there to provide that functionality in the first place).
>> 
>> On 8/6/19 14:08, Phil B wrote:
>> > I've always seen the value as being two-fold:
>> > 
>> > 1) To avoid needing to implement N #is* methods on Object (and there's a 
>> > lot more of this out there than just what the base image implements and 
>> > uses)
>> > 
>> > 2) As a mechanism to test for *protocol* compliance rather than *class* 
>> > membership of an object.  One may or may not agree with this 
>> > interpretation, but lacking a definition that said otherwise,  I decided 
>> > it meant this as well 😀
>> > 
>> > While implementations in the base image tend to have a 1:1 relationship 
>> > with a particular class, it is not required.  For example, I have a 
>> > number of classes that return true for #is: which aren't actually 
>> > subclasses of the thing they return true for but do behave as if they 
>> > were.  I don't care so much if a given object isKindOf: Morph, but 
>> > rather if it behaves as one.
>> > 
>> > There was a time when I tried to make the second use case more explicit 
>> > but there didn't seem to be a interest from others.  So I may be the 
>> > only person who makes use of the second use case today.  If so and 1 
>> > isn't seen as a worthwhile reason to stick with this approach, I can do 
>> > this another way.
>> > 
>> > On Tue, Aug 6, 2019, 3:21 PM Andres Valloud via Cuis-dev 
>> > <cuis-dev at lists.cuis.st <mailto:cuis-dev at lists.cuis.st>> wrote:
>> > 
>> >     So it looks like the #is: methods are there to implement the
>> >     functionality of #isXYZ messages with half the methods, which in turn
>> >     are there presumably to avoid having to send class or #isKindOf:.  But
>> >     one way or another, they are still class checks done in the language,
>> >     when the system already provides fast and invisible class checking in
>> >     every message send.
>> > 
>> >     In an old Cuis image that I have handy right now, there are 30
>> >     implementors of #is:.  There are 120 senders, but (essentially) 30 of
>> >     those are the implementors just mentioned.  So, 90 senders for 30
>> >     methods, a use factor of 3.  A brief look suggests a histogram, which
>> >     yields the following arguments for #is: (excluding the implementors
>> >     themselves).
>> > 
>> >     #(#Text #Color #Morph #Morph #Text #Morph #Form #Text #Morph #Form
>> >     #Text
>> >     #Text #Text #Form #Morph #Text #PluggableButtonMorph #CompiledMethod
>> >     #Morph #Color #Color #ColorForm #CompiledMethod #Stream #Text #Stream
>> >     #Morph #DateAndTime #DateAndTime #DateAndTime #DateAndTime #DateAndTime
>> >     #Text #Array #HandMorph #InnerTextMorph #InnerTextMorph #SystemWindow
>> >     #SystemWindow #HandMorph #MessageSend #Color #Text #ScrollPane
>> >     #CompiledMethod #Text #HandMorph #MenuItemMorph #MenuItemMorph
>> >     #MenuItemMorph #MenuItemMorph #UpdatingMenuItemMorph
>> >     #UpdatingMenuItemMorph #LayoutMorph #HandMorph #CompiledMethod #Stream
>> >     #Stream #Text #HandMorph #SystemWindow #HandMorph #MorphicEvent #Morph
>> >     #HaloMorph #Stream #Text #Text #HaloMorph #SystemWindow #Taskbar
>> >     #SystemWindow #SystemWindow #MessageSend #refusingToAccept #Text
>> >     #Rectangle #Rectangle #Rectangle #Rectangle #Rectangle #Text
>> >     #hasTextProvider #hasTextProvider #Stream #Text #Text #Text
>> >     #CompiledMethod #SystemWindow #SystemWindow #PluggableListMorph
>> >     #SystemWindow #SystemWindow #Taskbar #Text #Morph #Text #Text #Text
>> >     #DateAndTime #DateAndTime #DateAndTime #DateAndTime #DateAndTime
>> >     #UpdatingMenuItemMorph #ColorForm #MessageSend #MessageSend #Morph
>> >     #Morph)
>> > 
>> >     As a set, this collection has a size of 25 (so already this suggests
>> >     dead code is present).  Further, as an actual histogram, we see this:
>> > 
>> >     #Text -> 23
>> >     #Morph -> 11
>> >     #DateAndTime -> 10
>> >     #SystemWindow -> 10
>> >     #Stream -> 6
>> >     #HandMorph -> 6
>> >     #Rectangle -> 5
>> >     #CompiledMethod -> 5
>> >     #MessageSend -> 4
>> >     #Color -> 4
>> >     #MenuItemMorph -> 4
>> >     #UpdatingMenuItemMorph -> 3
>> >     #Form -> 3
>> >     #hasTextProvider -> 2
>> >     #HaloMorph -> 2
>> >     #Taskbar -> 2
>> >     #ColorForm -> 2
>> >     #InnerTextMorph -> 2
>> >     #PluggableButtonMorph -> 1
>> >     #LayoutMorph -> 1
>> >     #Array -> 1
>> >     #refusingToAccept -> 1
>> >     #PluggableListMorph -> 1
>> >     #ScrollPane -> 1
>> >     #MorphicEvent -> 1
>> > 
>> >     which suggests there is something going on, design-wise, with the top
>> >     20% because together they account for much more than 50% of the usage.
>> > 
>> >     So, even though as syntax I would find it just fine, I wonder if this
>> >     improvement is optimizing the highest priority problem.
>> > 
>> >     What has been the evolution / usage of this feature over time?  Where
>> >     should it go from here?
>> > 
>> >     On 8/6/19 04:54, Juan Vuletich via Cuis-dev wrote:
>> >      > Hi Folks,
>> >      >
>> >      > One thing I don't like about the #is: message is that being a
>> >     keyword,
>> >      > it usually requires parenthesis. Today I realized we can use #?
>> >     instead.
>> >      > So, we could write:
>> >      >
>> >      > aForm ? #GrayForm ifTrue: [ self doSomething ].
>> >      >
>> >      > instead of
>> >      >
>> >      > (aForm is: #GrayForm) ifTrue: [ self doSomething ].
>> >      >
>> >      > Do you like it? What do you prefer, #is: or #? ? Reasons for
>> >     adopting or
>> >      > not adopting it?
>> >      >
>> >      > Thanks,
>> >      >
>> >     -- 
>> >     Cuis-dev mailing list
>> >     Cuis-dev at lists.cuis.st <mailto:Cuis-dev at lists.cuis.st>
>> >     https://lists.cuis.st/mailman/listinfo/cuis-dev
>> > 
>> -- 
>> Cuis-dev mailing list
>> Cuis-dev at lists.cuis.st
>> https://lists.cuis.st/mailman/listinfo/cuis-dev
> -- 
> Cuis-dev mailing list
> Cuis-dev at lists.cuis.st
> https://lists.cuis.st/mailman/listinfo/cuis-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.cuis.st/mailman/archives/cuis-dev/attachments/20190806/c012f41e/attachment-0001.htm>


More information about the Cuis-dev mailing list