[squeak-dev] what is a transparent proxy?

christoph.thiede at student.hpi.uni-potsdam.de christoph.thiede at student.hpi.uni-potsdam.de
Sun Jan 30 00:02:31 UTC 2022


Hi all,

> That means Proxies could not be members of any HashedCollections without forcing reification.

Which just would be consequent if proxies do not have an own identity. This sounds to me like an optimization issue, though an important one, but not like a conceptual problem. If you want to create a proxy with its own identity, you could subclass an IdentityProxy from ProtoObject. :-)

Anyway, in SimulationStudio's Sandbox, I am using a pluggable dictionary that uses mirror primitives for the hash and equality blocks. But that might only make sense in the context of simulation.

> Yes, ok.   But better would be to introduce a set of selectors understood
> by ProtoObject and the relevant classes for checking arguments to
> primitives etc, i.e. for checking concrete types.  So ProtoObject and
> SmallInteger could implement isBasicSmallInteger and the code would read
> 
>     *at:* index
>         <*primitive:* 60>
>         index isBasicSmallInteger ifTrue:
>             [self basicClass isVariable
>                 ifTrue: [self errorSubscriptBounds: index]
>                 ifFalse: [self errorNotIndexable]].
>        index isNumber
>             ifTrue: [^self at: index asInteger]
>              ifFalse: [self errorNonIntegerIndex]

What is your conception of "selectors understood by ProtoObject"? I don't think ProtoObject should implement these messages itself (it probably wasn't even able to do so). One problem that I see with both #yourself and #asInteger is that it is not obvious for the programmer of a proxy that exactly these messages must not return proxies. Maybe a single, special selector like #asNonProxy would be more helpful? Or at least #asBasicSmallInteger? As mentioned earlier, I have a proxy that automatically answers new proxies via #doesNotUnderstand:. It should be as easy as possible to distinguish between messages that may answer a proxy and messages that must answer a VM-compatible object.

Other than that, #isBasicSmallInteger sounds reasonable. :-)

By the way, there are some other selectors with are not proxy-safe at the moment. For instance, myProxiesBoolean ifTrue: [...] would currently raise NonBooleanReceiver. But conceptually, this is no new issue. :-)

I like the overall ideas in this thread. I'm looking forward to addressing this after the release. :-)

Best,
Christoph

---
Sent from Squeak Inbox Talk

On 2022-01-18T00:48:50-07:00, drurowin at gmail.com wrote:

> Hi Chris, list,
> 
> I thought I'd add my voice in, as I've implemented pluggable proxies.
> 
> On Mon, Jan 17, 2022, 14:43 Chris Muller <asqueaker at gmail.com> wrote:
> 
> > > my understanding of a "transparent proxy" is that it automatically
> > forwards all requests, thus requiring special metaprogramming logic to
> > reveal an object as a proxy. On the other hand, "intransparent proxies"
> > would define an explicit list of requests to forward. Not sure however
> > whether this is a useful classification ...
> >
> > Then there is a balance between those two, traditional "Proxy", which
> > defines an explicit list of requests NOT to forward, any message not
> > in the list is automatically forwarded.
> >
> In my proxy code, I have this sort of "intercepting" proxy. There are also
> "before" and "after" message echo proxies, used for enforcing constraints
> and running triggers. I used it to build an object system.
> 
> That explicit list of requests is the API to the proxy, the
> > "metaprogramming logic" you alluded to, above.  As a Smalltalker, I
> > like to have that API defined on ProtoObject with "__" or "basic"
> > prefixes; i.e., #__class or #basicClass.  There could be one for each
> > mirror primitive, and nothing else.  That's my preferred aesthetic,
> > but the aesthetic of the Proxy API is less important to me than the
> > handling semantics needed throughout the code.
> >
> I agree! It needs to be very easy to use proxies. The more invisible they
> are, the better. If it's too difficult or results in rather un-Smalltalk
> code, people won't want to use them.
> 
> > > > - ProtoObject is still not yet an empty class.
> > > > > For instance, stuff such as #doOnlyOnce: or #scaledIdentityHash
> > should be implemented on Object only.
> >
> > That means Proxies could not be members of any HashedCollections
> > without forcing reification.
> >
> I disagree. They can still participate in identity hashing, as they have an
> identity. More on that later. Especially, the biggest use I have found for
> proxies is query result sets and efficient enumeration.
> 
> And it should be pushed as low into the code as it can to
> > maximize usage transparency.  (I realized your definition of
> > "transparent" was a function of the implementation, mine is a function
> > of their usage).
> >
> I don't like adding more things a garbage collector needs to know about,
> but between MNU overhead and #== being "no lookup", a functionally
> transparent proxy needs to happen at that level.
> 
> I'm not against a VM-based proxy system at all, the more options the better.
> 
> So long as it can be configured by object-level means, like subclasses, I
> prefer VM support over "pretty transparent but has gotchas". Needing to
> install the latest VM is not a big deal to me compared to reconfiguring an
> image.
> 
> Also, could it be offered as external?
> 
> It's just that we've allowed our anticipation of it to allow
> > Squeak's support for the classic Smalltalk Proxy pattern to get broken
> > (because of Symbol>>#=), so we currently have no options at all.
> >
> The way I looked at it was, a proxy is invisible to the object system. It
> doesn't exist. You can't test for it with #==, because it passes #==
> through itself. But, it does have an identity, since it's a 1st Class
> object, so you can ask *aProxy identityHash = aHash* and get something
> sensible out of it.
> 
> (It was a little more complicated than that. When you called #new the
> outermost proxy would be a anObject, which does understand #==. None of the
> internal components understood #== unless they were also anObject, which
> meant you had a chain. But that's for multiple inheritance.)
> 
> From,
> Lauren
> 
> >
> -------------- next part --------------
> An HTML attachment was scrubbed...
> URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20220118/a9d3d1e7/attachment.html>
> 
> 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20220130/18534301/attachment.html>


More information about the Squeak-dev mailing list