> On 17 Mar 2022, at 17:17, Richard Sargent 
> <richard.sarg...@gemtalksystems.com> wrote:
> 
> A pragma might be the way to go.
> 
> <noInline: #and:> for example.


There is already the #compilerOptions: Pragma, e.g.:

<compilerOptions: #(- optionInlineAndOr )>


For example this method compiled the and: as a real send:


tt
        <compilerOptions: #(- optionInlineAndOr)>

        true and: [ false ]

> 
> On Thu, Mar 17, 2022 at 8:17 AM Esteban Maringolo <emaring...@gmail.com 
> <mailto:emaring...@gmail.com>> wrote:
> Just to add another argument in favor of not inlining some message
> sends, is for instance in things like Glorp you need to use a special
> selector for #and:/#or: message sends, breaking not only the naming
> conventions but also the polymorphism.
> 
> E.g. you have to use #AND: and #OR: to avoid inlining.
> db read: YourClass where: [:inst | inst name = 'John' AND: [inst color
> = 'blue' OR: [inst color = 'red']]].
> 
> This is not only annoying, it also causes that if you want to to use
> something else as a backend (instead of Glorp), your block doesn't
> work anymore, which would perfectly work for a regular collection of
> elements using their underscore #and:/#or: equivalents.
> 
> The important thing, IMO, is that the core of OO is message sending,
> and enabling the receiver what to do with a message, which in the
> worst case would mean "I don't understand this message". A procedure
> call inverts the responsibility. A great trade off would be to be able
> to enable/disable for certain things instead of it being a global
> setting.
> 
> Regards,
> 
> Esteban A. Maringolo
> 
> On Thu, Mar 17, 2022 at 11:53 AM James Foster <smallt...@jgfoster.net 
> <mailto:smallt...@jgfoster.net>> wrote:
> >
> > Richard,
> >
> > I very much admire Dijkstra’s admonition regarding “The Humble Programmer” 
> > and was pointing a student to that article just this week.
> >
> > In any case, I think you’ve demonstrated that you now comprehend the 
> > argument against inlining—you just don’t agree. That’s fair and I think the 
> > discussion has been clarified. Would it be fair to say that you have an 
> > “ideological objection” to allowing a Proxy or Stub to transparently stand 
> > in for another object (say, in a two-object-space environment such as Pharo 
> > and GemStone)? That is, a domain object can’t be replaced by a Proxy or 
> > Stub without a wholesale rewrite of the rest of the application? I respect 
> > that as a reasonable position (demanding perfect clarity), but I see a cost 
> > to that position as well.
> >
> > Of course, if you really want to avoid allowing the receiver to chose its 
> > response to a message, you can use other messages. So if you want to find 
> > out if an object is identical to nil you should use `nil == myObject` to 
> > ensure that there was not an override of #’isNil’ or #’==‘ by the object’s 
> > class.
> >
> > James
> >
> > On Mar 17, 2022, at 2:27 AM, Richard O'Keefe <rao...@gmail.com 
> > <mailto:rao...@gmail.com>> wrote:
> >
> > My chief concern is that I am a bear of very little brain,
> > and if you change the meaning of #isNil to anything at all
> > other than "is the receiver identical to nil" you *WILL*
> > (not may) confuse me.  This extends to things that happen
> > not to be inlined: if even a god-like Smalltalker like
> > Andres Valloud overloads #, to something other than "combine
> > the collection that is the receiver with the collection that
> > is the argument to yield a new collection" than I *WILL*
> > most certainly be confused and find the code unmaintainable.
> > Smalltalk being Smalltalk, if you admit an inconsistent
> > overload anywhere, I can no longer understand sends of that
> > selector anywhere.  One of the things to like about Traits
> > is that you can say "this class doesn't just *happen* to
> > have selectors x and y, it has them *because* it has this
> > whole consistent bundle of selectors."
> >
> > There are more annotations documented for my Smalltalk
> > compiler than are actually implemented.  One that *is*
> > implemented is <doNotOverride>, and it has caught more
> > mistakes than I care to admit to.  It's particularly
> > important for a bundle of methods with varying arguments
> > that are meant to be routed through a single method,
> > which *is* meant to be overridden.  It makes sure that
> > I override the *right* method.  (Take #= and #~= as an
> > obvious example.)
> >
> > Once you start down the path of lying about things like #isNil
> > you find that EITHER you have to go very far down that path
> > and override #== and #instVarAt: and a whole lot of other
> > things OR you are working with a semantically incoherent system.
> >
> > "How should a proxy (https://en.wikipedia.org/wiki/Proxy_pattern 
> > <https://en.wikipedia.org/wiki/Proxy_pattern>) to nil respond to the 
> > #’isNil’ message?"
> >
> > It SHOULD NOT LIE.  A proxy *isn't* nil, and it doesn't *behave* like nil,
> > even if it is a proxy for nil.  A proxy, qua proxy, can do things that nil
> > cannot.  Use another selector, #isEffectivelyNil, or whatever reveals your
> > intentions, and give it what semantics you find useful.
> >
> > "How should the Null Object Pattern 
> > (https://en.wikipedia.org/wiki/Null_object_pattern 
> > <https://en.wikipedia.org/wiki/Null_object_pattern>) respond to #’isNil’?"
> >
> > It should answer false.  Period.  No ifs, buts, quibbles, or maybes.
> > The whole *point* of the Null Object Pattern is to return something
> > that *isn't* nil, that has quite a different protocol.  If you call
> > something that is supposed to return either a Foo or a NullFoo, and
> > it gives you nil instead, there is a BUG in what you just called so
> > the sooner you find out the better.  What you want is
> >
> >    Foo >> isNullFoo ^false
> >    NullFoo >> isNullFoo ^true
> > and no other class defines #isNullFoo.
> >
> > That way, when you ask "tripeWorks grobblingMill lastPallet isNullPallet"
> > (a) you make it clear to someone reading your code what you are expecting
> > (b) if you DON'T get what you are expecting, Smalltalk will tell you.
> >
> > I must admit that on the few occasions when I've used Null Object
> > I've used an all-purpose #isMissing instead of a task-appropriate
> > #isNullFoo, but then I figured out what I was doing wrong.  You
> > look at the code, you say "there's *something* off here, but I don't
> > know what."  But when you ask "what, exactly, does this method MEAN?"
> > you realise "oh, THAT'S what I was doing wrong."  #isMissing told me
> > it was a NullPerson or a NullAddress or a NullPartsList or ... but
> > in this case I needed to know whether it was a NullSummary.
> >
> > And of course you run into E.F.Codd's lesson: "one NULL is never
> > enough, information can be missing for more than one reason".
> > Take the familiar example of a phone number:
> >  - I know that Fred's phone number is X
> >  - I know that Fred has a phone but I don't know what the number is
> >  - I don't know whether Fred has a phone or not
> >  - I know that Fred has no phone
> > There's room for three *different* null objects there.
> > Should we have UnknownNumberOfActualPhone to answer false to #isnil
> > and NonNumberOfNonexistentPhone to answer true?  Or what?
> >
> > By the way, you may have misunderstood my benchmark.
> > It wasn't that #isNil or even _ ifNotNil: speeded up by
> > 10%, it was the *whole* matrix-munching benchmark that
> > speeded up.  Certainly not a big deal, but it's not
> > something I'd be happy to give up in order to get less
> > maintainable code.
> >
> >
> >
> >
> >
> >
> >
> >
> > On Thu, 17 Mar 2022 at 18:21, James Foster <smallt...@jgfoster.net 
> > <mailto:smallt...@jgfoster.net>> wrote:
> >>
> >> Richard,
> >>
> >> My _concern_ with inlining is that since it is designed to short-circuit 
> >> dynamic method lookup, it is impossible to call a _different_ 
> >> implementation. That is, you lose the opportunity to have the _receiver_ 
> >> decide how to respond to the message. You may think of it as a message, 
> >> but the caller is deciding how the receiver will respond—which largely 
> >> defeats the purpose and role of it being a message. Yes, at the machine 
> >> code level you are performing a branch instruction, but when comparing OOP 
> >> to Procedural Programming we typically make a distinction between 
> >> “messages” and "procedure calls." The distinction is that the receiver 
> >> gets to decide how to respond to a message. In C++ this is the distinction 
> >> between a “virtual" and "non-virtual" function. By inlining, you are 
> >> converting the function from a virtual function to a non-virtual function, 
> >> and this can make a difference (which is why virtual functions exist).
> >>
> >> How should a proxy (https://en.wikipedia.org/wiki/Proxy_pattern 
> >> <https://en.wikipedia.org/wiki/Proxy_pattern>) to nil respond to the 
> >> #’isNil’ message? How should the Null Object Pattern 
> >> (https://en.wikipedia.org/wiki/Null_object_pattern 
> >> <https://en.wikipedia.org/wiki/Null_object_pattern>) respond to #’isNil’?
> >>
> >> And, yes, I’m sure you can come up with benchmarks that show a measurable 
> >> difference, but what is the impact in realistic code? When someone asked 
> >> about inlining #’yourself’ in GemStone I believe I measured the 
> >> performance as taking 2 nanoseconds per call (on a 2012 machine). A 10% 
> >> speedup would make it 1.8 nanoseconds. Is that worth it? Maybe, maybe not.
> >>
> >> Note that I described my position as a “concern,” not an ideological 
> >> objection. Mostly I’m giving a rationale for something that doesn’t seem 
> >> to be explained very well for you. I accept that there may be a time for 
> >> inlining, but I can “comprehend" another side to the issue.
> >>
> >> James
> >>
> >> On Mar 16, 2022, at 9:42 PM, Richard O'Keefe <rao...@gmail.com 
> >> <mailto:rao...@gmail.com>> wrote:
> >>
> >> We're still not on the same page.
> >> You seem to have some ideological objection to inlining that
> >> I am completely failing to comprehend.
> >> Just because a procedure call (message send) is inlined doesn't
> >> in the least mean it *isn't* a procedure call (message send),
> >> just as compiling a procedure call (message send) as a jump
> >> (last-call optimisation) doesn't mean it *isn't* a procedure
> >> call (message send).
> >> By the way, forget about "40 years ago".
> >> I just did an experiment in Pharo 9, and found that
> >> using "_ ifNotNil: " instead of "_ izNil ifFalse: "
> >> -- where izNil is a non-inlined self == nil --
> >> gave a 10% speedup, in a test code where real work was going
> >> on as well.
> >> As for turning off all inlining, what do you think that would
> >> do to #ifFalse:ifTrue: and its relatives?
> >>
> >>
> >> On Thu, 17 Mar 2022 at 08:34, <s...@clipperadams.com 
> >> <mailto:s...@clipperadams.com>> wrote:
> >>>
> >>>
> >>> To start with, why do you CARE whether a particular method is inlined or 
> >>> not?
> >>>
> >>> I care because it makes “everything is a message” a lie! And I suspect 
> >>> (no proof and could be wrong) it’s an optimization that only made sense 
> >>> with the hardware constraints of 40+ years ago. Arguing against premature 
> >>> optimization is hardly something I just made up ;-)
> >>>
> >>> This makes absolutely no sense to me. What makes you think that the 
> >>> combination "_ isNil ifFalse: [_]" will NOT be inlined?
> >>>
> >>> I may have been unclear. My intent was to communicate: “I’d like to stop 
> >>> ALL* inlining of messages by default if possible”
> >>>
> >>> *or as many as practical
> >>>
> >>> The thing that rings loud alarm bells for me is there being "long chains" 
> >>> in the first place.
> >>>
> >>> I agree that it is in general a smell, but long chains was tangential to 
> >>> the intention above
> >>>
> >>> Can you give an example?
> >>>
> >>> I don’t know if I can think of one that’s not contrived… Wrapping 
> >>> something external? Squeak’s AppleScript support used to mirror the 
> >>> underlying AS, which is pretty much exactly that.
> >>>
> >>> In my own programming, I've generally found that nils turning up in the 
> >>> middle of a chain indicates a serious design error somewhere.
> >>>
> >>> Agreed. See smell comment above.
> >>
> >>
> >

Reply via email to