Pharo-users
By thread
pharo-users@lists.pharo.org
By month
Messages by month
- ----- 2026 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
March 2022
- 32 participants
- 104 messages
Re: Null Object Pattern
by James Foster
I donât understand. Wouldnât an override of #'doesNotUnderstand:â solve this problem? The proxies Iâve seen subclass from nil or ProtoObject and forward almost everything to the target. Itâs really very easy.
> On Mar 19, 2022, at 3:14 AM, Richard O'Keefe <raoknz(a)gmail.com> wrote:
>
> An object should be a Proxy or Stub only with reference to a specific protocol, which should be kept narrow.
>
> Being a Proxy is a form of coupling. Proxying a wide
> interface creates maintenance problems:
> Squeak 5.3 : Object selectors size => 485
> Pharo 9.0 : Object selectors size => 435
> astc : Object selectors size => 325
> VW 8.3PUL : Object selectors size => 304
>
> The interface of Object is HUGE. You want to bet that
> your Proxy got *all* of the methods right? This
> interface didn't get that way all at once; it grew.
> The number was 78 in Smalltalk-80. At a minimum, then,
> Smalltalk systems have accreted one extra Object method
> every two months.
>
> So you set up your proxy to *flawlesly* mirror Object,
> and then, WHOOPS, upgrade Smalltalk and now there is a
> method that Object has and your Proxy either lacks (if
> it descends from ProtoObject but not Object) or inherits
> an inappropriate version of (if it descends from Object).
>
> What this means is that nobody ever *does* flawlessly
> mock everything in the public interface of an object
> they are Proxying. They proxy a *limited* protocol.
> Because that is all they *can* do.
>
> Look, I know that people who have been trained to work
> with the stuff can use C4 as cooking fuel. But I haven't
> had that training, so I won't touch the stuff. In the
> same way, I dare say there are things *you* can safely
> do in Smalltalk that fumblefingers here would be burnt
> badly by. There are many things that *can* be done that
> I *won't* do. In a chemistry lab, I would not work with
> ClF3 let alone O2F2. In Smalltalk, I don't monkey with
> #isNil.
>
> On Fri, 18 Mar 2022 at 03:52, James Foster <smalltalk(a)jgfoster.net <mailto:smalltalk@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 <raoknz(a)gmail.com <mailto:raoknz@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 <smalltalk(a)jgfoster.net <mailto:smalltalk@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 <raoknz(a)gmail.com <mailto:raoknz@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, <sean(a)clipperadams.com <mailto:sean@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.
>>>
>>
>
March 20, 2022
Re: Null Object Pattern
by Richard O'Keefe
An object should be a Proxy or Stub only with reference to a specific
protocol, which should be kept narrow.
Being a Proxy is a form of coupling. Proxying a wide
interface creates maintenance problems:
Squeak 5.3 : Object selectors size => 485
Pharo 9.0 : Object selectors size => 435
astc : Object selectors size => 325
VW 8.3PUL : Object selectors size => 304
The interface of Object is HUGE. You want to bet that
your Proxy got *all* of the methods right? This
interface didn't get that way all at once; it grew.
The number was 78 in Smalltalk-80. At a minimum, then,
Smalltalk systems have accreted one extra Object method
every two months.
So you set up your proxy to *flawlesly* mirror Object,
and then, WHOOPS, upgrade Smalltalk and now there is a
method that Object has and your Proxy either lacks (if
it descends from ProtoObject but not Object) or inherits
an inappropriate version of (if it descends from Object).
What this means is that nobody ever *does* flawlessly
mock everything in the public interface of an object
they are Proxying. They proxy a *limited* protocol.
Because that is all they *can* do.
Look, I know that people who have been trained to work
with the stuff can use C4 as cooking fuel. But I haven't
had that training, so I won't touch the stuff. In the
same way, I dare say there are things *you* can safely
do in Smalltalk that fumblefingers here would be burnt
badly by. There are many things that *can* be done that
I *won't* do. In a chemistry lab, I would not work with
ClF3 let alone O2F2. In Smalltalk, I don't monkey with
#isNil.
On Fri, 18 Mar 2022 at 03:52, James Foster <smalltalk(a)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 <raoknz(a)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) 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) 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 <smalltalk(a)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) to nil
>> respond to the #âisNilâ message? How should the 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 <raoknz(a)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, <sean(a)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.
>>>
>>
>>
>
March 19, 2022
Re: Null Object Pattern
by Todd Blanchard
> On Mar 18, 2022, at 11:39 AM, Esteban Maringolo <emaringolo(a)gmail.com> wrote:
>
> You say that Smalltalk is not so hot for system developments because
> it's extremely malleable? What are you measuring it against?
Lots of things but to keep things simple lets go with Objective C since it is quite similar in concept and style but the library classes are closed to modification without extraordinary effort (you can replace a method but you're gonna have to work to do it because you don't have the source code for the core classes).
>
> It is still easy to break almost anything, without having to resort to
> compiler pragmas. :-)
Yeah, that's kind of my point. I have junked a lot of images in my wake.
>> If anything, I would like to see more immutable structure in the core classes. Add methods? Always. Casually override anything? There be dragons there.
>
> Something like "final" classes and "const" globals or not being able
> to extend classes such as [Proto]Object?
IDK exactly. Yeah, maybe a pragma that was part of the core library that would prevent an override of a key method that say, the browser, depends on.
Smalltalk is great for building things, but unlike when I build, say, a car, I don't have to drag around the entire factory I used to build the car behind it everywhere.
Toying with the idea of using one image to host remote developer tools that we do not change and using it to operate on a second image that has minimal dev tools but will be the production version of my app. That would provide the separation that would keep me from destroying toolkit by accident while trying to tweak the app.
Just musing here. I've become kind of dissatisfied with Pharo development of late. Hard to build anything that lasts very long.
>
>
>
>>
>> On Mar 18, 2022, at 11:06 AM, sean(a)clipperadams.com wrote:
>>
>> I feel like youâve latched onto something that is genuinely a non problemâ¦
>>
>> I wouldnât call complexity and lack of consistency a ânon problemâ, but it sounds like for you the practical implications outweigh my seemingly-somewhat-ideological/niche concerns. Is that a fair summary? In any case, I appreciate your perspective.
>>
>>
March 18, 2022
Re: Null Object Pattern
by Esteban Maringolo
On Fri, Mar 18, 2022 at 3:24 PM Todd Blanchard via Pharo-users
<pharo-users(a)lists.pharo.org> wrote:
>
> What, exactly, is inconsistent about a key message isNil being allowed to be overridden?
Overrides are not the issue here.
> There is a VERY simple solution to your problem that does not involve disrupting the platform.
No, it's not a simple solution.
> But you'd rather change the platform.
I'd bet that the change to inline those message sends came after the
implementation of the message sending.
> Part of the reason Smalltalk has not been the greatest platform to build software on is its extreme malleability. It is a double edged sword for sure. It is great for research. Not so hot for actual systems development.
You say that Smalltalk is not so hot for system developments because
it's extremely malleable? What are you measuring it against?
> "The key in making great and growable systems is much more to design how its modules communicate rather than what their internal properties and behaviors should be. <trim>" -Alan Kay
That's exactly the point of this conversion, a user might want the
modules to communicate by means of sending messages between them,
so writes the code with that expectation and then an external thing (the
compiler) decides to do something else that involves not actually
sending the message, because it focuses on the "internal properties
and behaviors".
> The inlined methods implement key operations that I believe *should* be immutable. Because the system is implemented in terms of itself, it is not very hard to completely destroy an image and render it unusable by overriding the wrong message in the wrong class (try overriding #environment at the class level and let me know how long before your image completely packs up under a torrent of walkbacks).
It is still easy to break almost anything, without having to resort to
compiler pragmas. :-)
> If anything, I would like to see more immutable structure in the core classes. Add methods? Always. Casually override anything? There be dragons there.
Something like "final" classes and "const" globals or not being able
to extend classes such as [Proto]Object?
In any case, I think the options for this inlining thing were laid on
the table, and there is a partial solution for these looking for
"semantic optimization" (as in true message sends) rather than
performance optimization (as in inlining).
Regards!
Esteban A. Maringolo
>
> On Mar 18, 2022, at 11:06 AM, sean(a)clipperadams.com wrote:
>
> I feel like youâve latched onto something that is genuinely a non problemâ¦
>
> I wouldnât call complexity and lack of consistency a ânon problemâ, but it sounds like for you the practical implications outweigh my seemingly-somewhat-ideological/niche concerns. Is that a fair summary? In any case, I appreciate your perspective.
>
>
March 18, 2022
Re: Null Object Pattern
by Todd Blanchard
What, exactly, is inconsistent about a key message isNil being allowed to be overridden?
There is a VERY simple solution to your problem that does not involve disrupting the platform.
But you'd rather change the platform.
Part of the reason Smalltalk has not been the greatest platform to build software on is its extreme malleability. It is a double edged sword for sure. It is great for research. Not so hot for actual systems development.
"The key in making great and growable systems is much more to design how its modules communicate rather than what their internal properties and behaviors should be. Think of the internet â to live, it (a) has to allow many different kinds of ideas and realizations that are beyond any single standard and (b) to allow varying degrees of safe interoperability between these ideas." -Alan Kay
The inlined methods implement key operations that I believe *should* be immutable. Because the system is implemented in terms of itself, it is not very hard to completely destroy an image and render it unusable by overriding the wrong message in the wrong class (try overriding #environment at the class level and let me know how long before your image completely packs up under a torrent of walkbacks).
If anything, I would like to see more immutable structure in the core classes. Add methods? Always. Casually override anything? There be dragons there.
> On Mar 18, 2022, at 11:06 AM, sean(a)clipperadams.com wrote:
>
> I feel like youâve latched onto something that is genuinely a non problemâ¦
>
> I wouldnât call complexity and lack of consistency a ânon problemâ, but it sounds like for you the practical implications outweigh my seemingly-somewhat-ideological/niche concerns. Is that a fair summary? In any case, I appreciate your perspective.
>
March 18, 2022
Re: Null Object Pattern
by sean@clipperadams.com
> I feel like youâve latched onto something that is genuinely a non problemâ¦
I wouldnât call complexity and lack of consistency a ânon problemâ, but it sounds like for you the practical implications outweigh my seemingly-somewhat-ideological/niche concerns. Is that a fair summary? In any case, I appreciate your perspective.
March 18, 2022
Re: Null Object Pattern
by Todd Blanchard
I feel like youâve latched onto something that is genuinely a non problem and if you get your way we all suffer reduced performance and a guarantee that a nil test is universally the same thing.
If you want an overridable nil test, write your own nil test like isNilish and make it mean what you like without disrupting the rest of the system. Problem solved and youâre not violating the open closed principle.
Sent from my iPhone
> On Mar 18, 2022, at 8:39 AM, sean(a)clipperadams.com wrote:
>
> 
> What you can do is turning it off globally in the setting (all compiler option are listed there)
>
> But take care: we can not recompile the image without optimzations as this adds intererrupt possibilities to code that was not interruptable before, which breaks the code in for process switching itself, I think.
>
> So it sounds like my daydream that inlining be turned off by default is a heavier lift than just flipping a switch, correct?
>
> In principle (ignoring the amount of work involved) what are your thoughts RE my musing: âAfter 40+ years of Mooreâs Law, can we turn off these inlines by default?â and my hypothesis that this is an optimization that made sense at the time but now adds complexity for questionable payoff?
March 18, 2022
Re: Null Object Pattern
by sean@clipperadams.com
> What you can do is turning it off globally in the setting (all compiler option are listed there)
>
> But take care: we can not recompile the image without optimzations as this adds intererrupt possibilities to code that was not
> interruptable before, which breaks the code in for process switching itself, I think.
So it sounds like my daydream that inlining be turned off by default is a heavier lift than just flipping a switch, correct?
In principle (ignoring the amount of work involved) what are your thoughts RE my musing: âAfter 40+ years of Mooreâs Law, can we turn off these inlines by default?â and my hypothesis that this is an optimization that made sense at the time but now adds complexity for questionable payoff?
March 18, 2022
Re: Null Object Pattern
by sean@clipperadams.com
> 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.
I can understand your probably well-justified concern that power can always be misused. I also understand a key principle of Smalltalk to be âempower and trust the programmerâ. Edge cases like this where Smalltalk principles like pervasive message passing are not true bring their own share of confusion.
> "How should a proxy (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.
I find the concept of âisâ and âequalâ to be generally confusing in Smalltalk. Does \`#=\` mean âall state is the sameâ? âall relevant state is the same (minus e.g. caching)â? âThis represents the same domain objectâ?
I can see how a proxy claiming to be nil is a âlieâ for one/some definitions of âisâ, but I donât think itâs universally true.
Really interesting conversation!
March 18, 2022
Re: Null Object Pattern
by sean@clipperadams.com
> 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, this is exactly the point I was (apparently badly) trying to convey. Thanks!
March 18, 2022