[Cuis-dev] Expanding on #noteCompilationOf:meta:

Phil B pbpublist at gmail.com
Wed Jan 22 09:55:59 PST 2020


Hernan,

On Wed, Jan 22, 2020 at 4:37 AM Hernan Wilkinson <
hernan.wilkinson at 10pines.com> wrote:

> Hi Phil!,
>  it is interesting what you are proposing. I'd like to understand a little
> bit more the motivation, why you did it that way, etc., so I have a few
> questions :-)
>

Before addressing your specific questions, it might be helpful for me to
clarify where I'm coming from a bigger picture standpoint:  I don't like
how hard coded and brittle much of the infrastructure in Smalltalk is.
I've complained about it before so this should come as no surprise ;-) This
is a small step towards addressing one aspect of this.  We have
#noteCompilationOf:meta: and no one seems to mind so I thought 'why not
extend it so we can have more of a lifecycle view of methods?'  While it's
far from a Smalltalk MOP implementation that Alan Kay has talked about,
using a mechanism like this seems to me a better approach than either
needing to override a number of inconvenient methods and/or baking in
features other people many not want to avoid doing said overrides rather
than just reacting to method changes as desired.  So by adding a few more
hooks around method creation/removal, I can get the functionality I need
without either making someone else's life more difficult or my own.


> 1) Do you have a real case scenario for this feature? I'd like to know the
> use that we could give it. I would like other peoples opinion on this too
> because it is a change in the core.
>

Of course! (I never proposes changes that I don't have a need for ;-)  The
main categories of use cases I have in mind are:

1) One wants to track senders or implementors of arbitrary methods at an
aggregate level.  These can be relatively expensive things to compute,
especially in bulk.

2) One wants to keep metadata of particular senders/implementors of a
method in sync/updated as the image changes.  Some of this metadata may
alter the behavior in other parts of the image, including potentially
regenerating/recompiling code elsewhere.

3) Allow for (partially) fixing one of my long standing gripes about the
image (see my response to your #3 below)

One of the things I'm continually running into is that the runtime
structure of the image is just too brittle.  Sure, you can dynamically
add/remove methods, but the mechanism for having other code react to these
changes in realtime, and/or at a global level, is lacking.  This is what
these proposed additions are attempting to address.


> 2) Why would not only redefine #compile:... and #removeSelector: for the
> classes that you need that behavior? (it is related with 1) and I think I
> know what your answer will be, but I ask just in case :-) )
>

That would work if all you wanted to do is track *a* sender/implementor of
a method in a given class hierarchy, but not *all* senders/implementors of
it (and there may not be an 'it': you might just need to track everything
that is changing) across the image.  Put another way, the solution you
suggest addresses it from a class-centric perspective, my proposal allows
for addressing it more from a message-centric perspective.

The methods I'm proposing to add are all similar to
#noteCompilationOf:meta: in that when you need them, they are pretty much
the only way I can see to efficiently and reliably do it.  While we could
potentially re-implement some existing functionality using it (again, see
#3 below) I am not proposing any new use cases for it in the base image.
So they're essentially just hooks for those who need the functionality.
Anyone who doesn't care can just ignore them as they do currently with
#noteCompilationOf:meta:.  (i.e. it's infrastructure, not a feature)

3) Why do you signal an error if compilation is not allowed? That is
> changing the contract of #compile:... and I'm not sure that an exception is
> what users of #compile... would expect in that case. Also, in the case of
> not removing a method you do not signal an exception making the behavior of
> "not doing" kind of "inconsistent"
>

You are correct that an error was the wrong way to do it and that an
exception would be better... I'm fine with changing that.  However, I'm not
going to let you take both sides of the argument re: the rest... :-)

This is pretty much providing identical functionality to the existing hard
coded warnings/errors in the image when you attempt to override particular
key/core methods and classes.  In addition to breaking a contract, the
hard-coded rules seem rather antithetical to the Smalltalk philosophy.  My
proposal doesn't really allow for the breaking of anything new, just
changing the way in which one breaks the contract to allow for it to be
done in a user defined/overridden and dynamic way.

I would greatly appreciate it if things like
ClassBuilder name:subclassOf:type:instanceVariableNames:classVariableNames:poolDictionaries:category:unsafe:
(granted this is for classes, but is an example of the general complaint)
and the variable shadowing errors operated more like this.  So that's where
the idea for the #isOK* methods came from: let's move policies like these
into this method and if I don't like them or need different ones, I have
something more straightforward and less brittle to override.


> 4) The redefinition of #isOkToCompile:meta, #isOkToRemove:meta: and
> #noteRemovalOf:meta: in Object class are not necessary, as far as I can
> see, why did you redefine them there?
>

I was following the lead of the #noteCompilationOf:meta: Object override
here.  This is related to my query related to #removeSelector: that
follows...


>
> About your question of #removeSelector:, I don't quite understand you
> question, I think you are missing the meta class part there. I mean, I you
> have class XX and it has a class method, let's say #m1 and you want to
> remove it, you have to do:
> XX class removeSelector: #m1
>
> The method that will be evaluated for that message send will be the one
> implemented in ClassDescription, as with a class because Metaclass and
> Class are subclasses of ClassDescription.
> Does it make sense what I'm saying? or am I not understanding your
> question?
>

Apologies, I didn't state the question/issue very well...

Look at where the implementors for #noteCompilationOf:meta: and
#removeSelector: are.  For #removeSelector: the ClassDescription
implementor gets called for instance methods, Behavior for class methods.
Yet for #noteCompilationOf:meta: it's ClassDescription for instance methods
and Object (per the method comment) for class methods.  I was expecting
more symmetry here (i.e. #noteCompilationOf:meta: essentially being a
method add/change and #removeSelector: being method removal) and wondering
if there was a reason they ended up where they did or if no one has really
thought about it before?  So that's why I put those methods in Object: it
seemed like they *should* be needed and functional there. (i.e. I did note
the class-side problem ;-)  I don't really care where they go, but the
add/change/remove methods probably should go there together.


> Cheers!
> Hernan.
>

Thanks,
Phil


>
> On Sat, Jan 18, 2020 at 8:08 PM Phil B via Cuis-dev <
> cuis-dev at lists.cuis.st> wrote:
>
>> Attached is a first cut of something I've wanted for a while: the ability
>> to capture method changes as they occur with the ability to prevent them
>> from happening if needed at a global level.  Basically it's just paired
>> methods of #isOkTo[Compile|Remove]:meta: and
>> #note[Compilation|Removal]Of:meta:.
>>
>> It's always bothered me how central the method  structure is yet
>> completely useless from the standpoint of having extensible metadata... if
>> I'm wrong re: extensibility, please let me know what I've overlooked.  So
>> barring that, these changes allow for things like helping to keep a
>> separate metadata structure in sync with method changes.  The main
>> requirement is to be able to track method adds, changes and deletes to the
>> image globally.  Not sure, but I was thinking that this facility might also
>> be useful for refactoring tools.
>>
>> One issue / odd thing I noticed: the removal methods only get called
>> instance-side due to ClassDescription #removeSelector: only getting called
>> on instance methods and you have to jump up to the Behavior implementor for
>> class methods.  That seems strange to me since method compilation all
>> appears to occur at the level of ClassDescription.  Is there a reason
>> removals need to be different from compilation in this way?  (Not knowing
>> the answer, I haven't fixed this issue in the attached changeset)
>> --
>> Cuis-dev mailing list
>> Cuis-dev at lists.cuis.st
>> https://lists.cuis.st/mailman/listinfo/cuis-dev
>>
>
>
> --
>
> *Hernán WilkinsonAgile Software Development, Teaching & Coaching*
> *Phone: +54-011*-4893-2057
> *Twitter: @HernanWilkinson*
> *site: http://www.10Pines.com <http://www.10pines.com/>*
> Address: Alem 896, Floor 6, Buenos Aires, Argentina
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.cuis.st/mailman/archives/cuis-dev/attachments/20200122/9dd38fab/attachment-0001.htm>


More information about the Cuis-dev mailing list