[squeak-dev] Traits use to provide class protocol in a browser?
rabbit at callistohouse.org
Mon Oct 10 13:52:27 UTC 2022
> On Oct 9, 2022, at 18:56, Jakob Reschke <jakres+squeak at gmail.com> wrote:
>> 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. ;-)
Secrets are overrated. Causes potential paranoia; will destroy ya! ;-)
> 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.
Agreed. It takes time and serious efforts to turn my stream of consciousness design journaling into a cogent, structured design, with a prioritized task list.
As you can see, this ETrait topic is #10, while our other conversation is #12. So much to do first! #1 through #3 are crucial first objectives. 🐰
1) Get ASN1 working
2) Update ASN1 tags
3) Remote Promises
4) Use E-API #identityHash & #becomeForwards:preserveIdentity
5) Start using E-SSE ->
Eventual-Sending Style Evals
6) Work up ELinda (ELindaSubspaceArray)
7) Provide #asTuple and #asTupleMatcher
8) Switch … to use ELinda
- eventualize internally (ESubspaceArray)
- a) VatZ!!!
- b) ASN1Module!!!
9) Sessions, Services & Brokers / Specs
- build Specs (rename Configs)
- ReplicaSession (3 channel replication)
- concrete ERef subs 4 specific services
- method overrides
- remote discovery
- immediate push updates on changes
11) Matching strategies
12) SqueakMap head & release
13) Caching strategies
>>> 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.
Yessir, totally understood. Within the same image, we’ve a working solution. Beyond that, hand-crafting distributed meta event update tasks, acceptable and expected.
>>>>>> 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.
I expressed myself poorly.
> 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?
I meant that a Browser executes code, potentially freshly installed, to do
It’s thing. Whether that code is a CompiledMethod or a BlockClosure really makes no difference (I got off track bringing up BlockClosures). My main point being live execution is the Way of the Squeak.
I see now your point was using full on CompiledMethods solely for documentation. It’s clearly more than simply documentation, allowing users to modify a specific services proxy implementation for local side effects. I’m thinking now that that’s a desired feature.
> 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?
Yessir. Eventual forwarding happens both in the NearRef case and in the FarRef case, though with different internal implementations, of course. But we’ve no service protocol descriptions within the scope of an instance of ERef, near or far. In the near case, the proxied service Class in co-located, and the NearRef instance is aware of this class:
^ self resolution class.
So no concrete subclasses of NearRef. The FarRef case is different. It may be the FarRef proxies for an unknown remote subject class defined in its host, only. I wish to
a) provide a way to explore its protocol in a standard Browser
b) allow local overrides to be engineered
c) have a concrete proxy subclass (ConcreteServiceFarRef) for remote subjects.
> 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.
My delay in responding was to gain a little timespace to look into PseudoClass, which specifies the protocol of a ting without method implementations. That would support (a), but not (b) or (c).
Allow me to thank you for your helping me develop my idea of the desired features and consolidate my thinking.
I prefer viewing proxied protocol in a regular Browser (a) plus (b) & (c) as well. This supports my desired workflow:
E-SSE Debugging Workflow: Inspect a FarRef. Browse full. Explore concrete protocol for proxied Class.
> 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.
Not I, either, aside from knowing a PrologCompiler is defined and the Browser supports different Compilers for different languages. With this eventual-sending extension to the core Smalltalk execution paradigm (immediate message passing vs eventual sending), I don’t think it rises to the level of requiring a new Compiler yet I am totally open and welcoming toward being convinced to change my mind, always!
>>>> 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...?
They are remote and foreign to the local Vat, so they must be FarRefs. Whether there is a special case FarRef for system calls is actually a special case of the SecureSessionStack. Perhaps use a SyscallThunk rather than a SocketThunk?
My view is that would be an optimization to a functional “remote” case, that currently works in all these three cases, all “remote” to the local Vat:
1) same Squeak VM instance different co-located VatZ
2) VatZ on same machine different VM instances
3) VatZ on different machines
>>>> 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.
Perhaps the service class’ host should generate the ConcreteServiceFarRef subclass itself, skip Trait generation and send that class to the client. As there is only one class needing the proposed Trait, as you observe below, just generate the class, send it and install it locally, then #becomeForward: the FarRef instance to be a ConcreteServiceFarRef subclass instance…should meet the requirements!
Which Way is Which What?
> 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.
Please see FarRef requirements (a), (b) & (c) above. Any issues with those requirements you think, Jakob? With this new idea of direct ConcreteServiceFarRef generation and distribution?
>>>>>> 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.
Yes too many different concepts poorly described…mea culpa!
> Talking about two Squeak instances that are connected through your system, where are these various classes situated, and which ones are proxying for another?
I would say two VatZ remote from each other, whether 1, 2 or 3, defined above. They are all the same!
> 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.
Yes, now the idea we’ve arrived at is generation of the ConcreteServiceFarRef on the right side.
> Should the tools talk to something on the right side, through your system?
No, I agree with your point: the tools are not eventualized.
> 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),
Yessir! Exactly my thinking now!
> or better a PseudoClass, or just a collection of the selectors that the real class can understand, rather than a trait?
These are not discoverable in a Browser from an instance, so it fails requirement (a) and breaks the E-SSE Debugging Workflow. :)
> 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.
Yessir. I grok it now. Not to get too repetitious, but for clarity in our conversation : no Trait generation; we have arrived at the model of host generated ConcreteServiceFarRef.
> 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.
Yes, has the previous discussion ameliorated our shared understanding?
> 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.
I also understand this concern. Not sure yet…’UserFarRefs’ package category? Too many ConcreteServiceFarRefs subclasses?
>>>> 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...
Yes indeed! No longer any concern of mine what other folks do or do not do. In my peaceful place I actively cultivate, I abide and remain unconcerned.
Sat chit ananda: existence, knowledge, bliss!
Thank you for your understanding! And thank you sincerely for your efforts to understand and taking the time to help me, Jakob! You are a blessing!
Have a good one; keep it, light.
. .. … ‘…^,^
Sent from Callisto House Mobile
:: decentralized mobile homeless solutions
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Squeak-dev