[squeak-dev] Traits use to provide class protocol in a browser?

Jakob Reschke jakres+squeak at gmail.com
Sun Oct 9 22:55:57 UTC 2022


Am So., 9. Okt. 2022 um 20:15 Uhr schrieb rabbit <rabbit at callistohouse.org>:

> Jakob, May I receive your permission to add this email thread to the
> ESqueak Design?
>
>
Sure why not. If I wanted to keep anything that I share here secret, I
would not share it here. ;-) But in my opinion, email threads hardly make
good documentation. I always roll my eyes if I find a Squeak Wiki page that
is just a collection of copy&pasted emails.


> On Oct 9, 2022, at 14:11, rabbit <rabbit at callistohouse.org> wrote:
>
> On Oct 9, 2022, at 11:42, Jakob Reschke <jakres+squeak at gmail.com> wrote:
>
> 
> Am So., 9. Okt. 2022 um 13:56 Uhr schrieb rabbit <rabbit at callistohouse.org
> >:
>
>> On Oct 9, 2022, at 06:01, Jakob Reschke <jakres+squeak at gmail.com> wrote:
>>
>> 
>> Hi rabbit,
>>
>> Traits are used by classes, not by instances, but traits can
>> supply methods both to the instance side and the class side.
>>
>>
>> Yes I understand this…still…I would generate an ETrait from the
>> eventualeé’s Class. For now we’ll assume a spherical cow and so the
>> eventualeé’s class is local. This is our useCase, an ETrait…
>>
>> If that class were unknown to the client, an eventual ‘eref class
>> asETrait’ would return the ETrait for that class over the inet to the
>> client, in an archived box, pass-by-copy, a later detail. Spherical cow.
>>
>>
> Is there a particular reason to send/make a trait rather than a class? In
> particular if you need dynamically generated subclasses of ERef anyway.
>
>
> My suspicion was Squeak’s Traits provided methods and perhaps could
> update. Which it does! Yay!
>
> But it updates methods / propagates changes only within the same image.
For anything beyond, you have to take care of the synchronization. You can
use Distributed ELinda or anything else to accomplish that, sure. But
traits will not do the work for you.

If you use a trait in a class, the trait's methods are copied to the
>> MethodDictionary of that class (and the corresponding classTrait methods go
>> to the dictionary of the corresponding Metaclass).
>>
>>
>> Right so what are the method implementations of an ETrait? This is the
>> key to my using them. As this is strictly for documentation and browsing of
>> the class of an instance, for those developers who ask “what are the
>> messages I can send to my ERef?” Open a browser on its class and see!
>>
>
> Not sure whether putting something that the system can potentially
> execute into the system is the right way to obtain something "strictly for
> documentation"...
>
>
> I’m confused. That’s just constructing BlockClosures with anonymous code
> to run, right? That’s how a Browser works, right?
>
> Errm, no. Unless we are talking about different things. If you save a
method in the browser, the compiler produces a CompiledMethod, which gets
installed in the class's method dictionary. No BlockClosure here.
But even if it were so, a BlockClosure would be even less suitable as a
piece of documentation, wouldn't it?

Let me rephrase my original, complicated sentence:
You want to make the protocol of the remote object discoverable. You
already have the mechanism to send messages to the remote—that is
your doesNotUnderstand: implementation in the ERef, right? Why install
further methods in the local system, just to put up something that can be
browsed with the existing tools? Instead you could do it like the
FileContentsBrowser and use PseudoClass to give the user something
browseable, without actually loading methods or creating classes that
mirror the remote class in some way. Or generate a HelpTopic and open that
in the HelpBrowser...

So as E-SSE is different, an extension to Core Smalltalk, a custom browser
> needs be provided. The Browser was built to support that and Prolog
> provides an Excellent example! I’ll get that loading soon. I believe it’s
> not been published to the SM 6.1 version. I know very little about it. Can
> you tell me more?
>
> No, I have not looked at the Prolog implementation.

Even if this all runs in the same image, and the spherical cow just runs in
> a different Vat than the one where the ERef to it is,
>
>
> Yessir, multiple Vats within the same system goes through sockets so
> samesame.
>
> Is it not unnecessarily expensive to go through OS system calls for the
sockets when you just want to talk to the neighboring objects in the same
image...?

And then, once more, why generate both a trait and a subclass, when just
> the subclass would be enough.
>
>
> Ah, I understand your point now. Why Double generation you’re asking. In
> my view, I’ve pointed out it’s a functional update mechanism, just double
> meta generation. One at the remote Class host and one in the local
> TraitERef case. Also it’s a publishable artifact that’s distributable.
>
> How else to send method updates? BTW, sending an eTriggerEvent: exactly
> when the method is compiled into the Class provides immediate update push
> events.
>
> Well, as I wrote above, traits do not do any of this for you. They are
also not more suitable to be transferred over the wire than a regular
class, as far as I can tell.

The purpose of traits is to share common method implementations among
classes that are not related via the class-superclass relationship. As is,
this only works within the same image. Moreover you do not want to share
implementations, only information about the protocol. So I do not see how
traits would help you.

When you implement your own method in the class, even though that method
>> would also be provided by a trait that the class uses, the trait will skip
>> that method and leave your own method in place.
>>
>>
>> Not necessary, I think. Possible to specify read-only method
>> implementations?
>>
>
> What do you mean "Not necessary"?
>
>
> The Class Host has generated  it’s ETrait with forwarding methods already.
> Advisable not to change the methods in a ETraitERef class.
>
> Maybe I have some misunderstanding. You are mentioning many different
class names and terms from your system about which I have almost zero prior
knowledge. Talking about two Squeak instances that are connected through
your system, where are these various classes situated, and which ones are
proxying for another?

Example table:
|| System that uses the spherical cow || System that hosts the spherical
cow ||
| ERef | SphericalCow (= the "eventualeé's class"?) |
| ETraitERef (is this a subclass of ERef?) | ETrait? |
| ETraitERef for the protocol description of SphericalCow | Generated
ETrait that describes the protocol of SphericalCow? |
| Generated trait that describes the protocol of SphericalCow? | n/a? |
| Generated subclass of ERef (?) for the SphericalCow? (is supposed to use
which of the two traits above?) | SphericalCow |

The browsing of the protocol is supposed to happen in the system on the
left side of the table. So far I was thinking that what you are talking
about is supposed to happen only on the left side of the table. But maybe
you had in mind to implement some things on the right side instead.

Should the tools talk to something on the right side, through your system?
If this was your idea, I would assume that the immediate problem is that
none of the existing Squeak tools/browsers can deal with EPromises that
the ERef proxy being browsed would return for any query message that the
browsers send to it.

So either you need tools that can deal with EPromises, or you do need to
transmit some protocol description explicitly and browse that instead. I
was assuming the latter, and you also mentioned encoding the trait and
passing a copy of it. And if that is so, why not directly pass a copy of a
class (that has the EMessageSend in each method rather than the actual
implementation), or better a PseudoClass, or just a collection of the
selectors that the real class can understand, rather than a trait?

A trait may be seen as a collection of methods that happens to be
browseable with the Smalltalk tools, but, I repeat, its purpose is to share
implementations among unrelated classes. Apart from the fact that you do
not wish to share implementations, that sharing does not work out of the
box across the middle vertical line of the table above. And looking at only
the left side in isolation, or only the right side, I do not see yet where
this implementation sharing would be beneficial.

What is also unclear to me is when you want to transmit this protocol
description. Just in time when the user wants to browse the protocol of the
remote object? Or as soon as the left side establishes the reference to the
object on the right side? If you wanted the ERef object to be a member of a
generated subclass that is tailored to proxy one specific class from the
remote system, it would only make sense to me with the second option. But
it may be overkill to create a tailored proxy class for every remote class
that you encounter.

there is no possibility that I know of to avoid that trait methods "back
> out" if the class already up has a method that the trait also provides.
>
>
> Yes, this is what I’m trying to block a naive user from being able to do.
> IDK,
>
> Then I advise against giving them some piece of Smalltalk in the first
place. At the heart of Smalltalk is that you can change anything about the
system if you want to. Alternatively, just let them try to change it.
Nobody prevents naive users from evaluating `true become: false` either...
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20221010/35cdfdcf/attachment.html>


More information about the Squeak-dev mailing list