Direct proxies update

Allen Wirfs-Brock allen at
Mon Nov 28 21:36:35 PST 2011

On Nov 29, 2011, at 2:50 AM, David Bruant wrote:

> Le 28/11/2011 01:07, Allen Wirfs-Brock a écrit :
>> On Nov 26, 2011, at 11:52 AM, David Bruant wrote:
>>> Le 24/11/2011 22:29, Tom Van Cutsem a écrit :
>>>> 2011/11/24 Allen Wirfs-Brock <allen at>
>>>> If we are going to have a @reflection module that is of broader applicability then just writing proxy handlers I'd  like us to consider a Mirrors style API.  Otherwise I'm a concern will continue to have a proliferation of reflection APIs as we move beyond Proxies into other use cases.
>>>> I'm not sure I understand. Additional reflection functionality can easily be added to the @reflect module. It need not be exclusive to Proxies.
>>>> At is a first cut of a mirrors API that I threw together earlier this year for JavaScript.  I don't hold it up as a finished product but it could be a starting point for this sort of design.
>>>> At the core is a root question whether we want to expose a functional or object-oriented API for reflection functionality.  These are two different styles each of which is probably favored by a different subset of our user community.  I suspect that everyone knows which sub-community I align with. The main argument for the OO style is that it allows creation of client code that can be oblivious to the underlying implementation of the API.  The                         allows for more flexible client code that has greater potential for reuse.
>>>> I'm sympathetic to mirror-based APIs myself. However, note that a mirror-based API would require an extra allocation as opposed to the proposed API:
>>>> // Proposed API:
>>>> Reflect.has(object, name)
>>>> // Mirror-style API:
>>>> Mirror.on(object).has(name)
>>> I have been thinking about this a lot and I don't find any advantage to "Mirror.on(object).*(" over "Reflect.*(object," ... for local objects.
>>> After reading , I have realized that the mirror API aims at more than providing reflection with a uniform API for other sorts of objects including, for instance, remote objects.
>>> Unfortunately, I am not sure I can go further, because I haven't found a definition of what a remote object is and don't really know how reflecting on them differs from reflecting local objects.
>>> Among the questions:
>>> * What is a remote object?

In reflection discussion, it often means an object that exists in a isolated object domain that is distinct from the object domain that is needs to examine/manipulate the object.  For example, think objects within a web worker. Typically we are talking about  objects of the same language in both domains.

The canonical example is a tool such as an object inspector that you would like to be able to target at either local objects (objects in the same object domain as the inspector implementation) or "remote" objects. 

>>> * How does it differ from a local object?

There is no direct way to reference a remote object (it is in a different object domain) so any primitive reflection APIs that are based upon local object references can't manipulate a remote object.

>>> * Do you need a local object to "emulate" a remote object?

That is essentially what a local mirror on a remote object is.  It makes a remote object accessible using the same reflection API that is used to access a local object.  It accomplishes such uniform reference by adding a level of indirect to all reflection APIs, even local direct object accesses. 

>>> * Does reflecting on remote objects impose synchronisity (waiting for the remote object to "respond" before telling what the answer is)?
>> Did you look at my blog posts and the jsmirrors code.  It includes an example of using a common mirror API to access both local objects and a serialized external object representation. such an representation can easily be used to           access live remote objects.
> I agree, but I don't understand how you can use the same API for both local and remote objects. Or maybe you don't (retrieve representation async-ly and create the mirror when the representation is here)?

I'm guessing (let me know if I'm wrong) that what you are missing that leads to the above question is that "object reference" arguments to mirror methods (and return value) are themselves mirrors rather than direct object references.  So, assume we have executed something like:
     let mr = Mirror.on(someObject); //someObject is a regular object reference

then, assuming that object mirrors have a "get" method for accessing a property value an expression like:

     let m2= mr.get('propName');
     //m2 is a mirror on the value of someObject.propName
    let m3 = m2.get('anotherName);
    //m3 is a mirror on someObject.propName.anotherName

If instead we had initialized mr as:

   let mr = RemoteJSMirror.on(remoteObjectURL);
   let mr = JSONSerializationMirror.on(jsonString, rootID);
 the above code sequence for setting m2 and m3 would still be valid.  The only difference is that that values of m2 and m3 would be either RemoteObjectMirror or JSONSerializedObjectMirror instances instead of NativeObjectMirror instances .  (all just made up names).

The only issue that I know of relates to the fact that access to remote objects state probably requires the use of async APIs and call backs while all of the Mirror APIs I have ever seen are most naturally expressed in a synchronous style.  I'm not sure what the best resolution of that issue will be.  It certainly would be possible to make an async mirrors API that also works with local objects.  Anybody writing code that needed to work with any kind of mirror would want to use that async API.  However, that would be awkward and expensive for cases where you know that synchronous access is possible, such as probably most Proxy uses of reflection. Perhaps for those cases a simpler synchronous mirrors API is needed.  Unfortunately, that would leave us with two variants of the mirrors API.

BTW, it occurs to me that there probably is a similar issue if anyone tries to use Proxy to actually create a remote object access facade.   Proxy Handler calls are synchronous but what if a trap handler (say a get) needs to make an async call to a to obtain the state needed to produce the value returned by the trap... 


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list