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

Andres Valloud ten at smallinteger.com
Tue Aug 6 21:16:08 PDT 2019


On 8/6/19 19:03, Phil B wrote:
> 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.

I agree, just because something is there is not valid grounds to use it.

> 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.
> 
> 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.

I can see some of that.  In "normal" circumstances, like what I saw when 
I reviewed those senders of #is:, I still think #is: is more a symptom 
than a feature.

Andres.

> 
> On Tue, Aug 6, 2019 at 7:28 PM Andres Valloud via Cuis-dev 
> <cuis-dev at lists.cuis.st <mailto:cuis-dev at lists.cuis.st>> wrote:
> 
>     The argument seems to be that undesirable forms of polymorphism can be
>     avoided with #is: messages--- yet the #is: messages are polymorphic
>     themselves.  Why, exactly, is the polymorphic use of #is: better than
>     other forms of polymorphism?
> 
>     To me, that kind of usage reimplements by hand what the VM is
>     working so
>     hard to provide.  The result is code that is slower (the system has
>     more
>     to do), and bigger (my brain has more to think about).  But don't
>     repeat
>     yourself, once and only once, and all that.  So I'd rather not.
> 
>     On 8/6/19 15:39, Phil B 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 <mailto:cuis-dev at lists.cuis.st>
>     <mailto:cuis-dev at lists.cuis.st <mailto: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>
>     <mailto:cuis-dev at lists.cuis.st <mailto:cuis-dev at lists.cuis.st>>
>      >     <mailto:cuis-dev at lists.cuis.st
>     <mailto:cuis-dev at lists.cuis.st> <mailto: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>
>     <mailto:Cuis-dev at lists.cuis.st <mailto:Cuis-dev at lists.cuis.st>>
>      >     <mailto:Cuis-dev at lists.cuis.st
>     <mailto:Cuis-dev at lists.cuis.st> <mailto: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 <mailto:Cuis-dev at lists.cuis.st>
>     <mailto: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 <mailto:Cuis-dev at lists.cuis.st>
>     https://lists.cuis.st/mailman/listinfo/cuis-dev
> 


More information about the Cuis-dev mailing list