Tech talk on proxies and traits

# Tom Van Cutsem (14 years ago)

I recently gave a Google tech talk on my joint work with Mark S. Miller on Harmony proxies and the traits.js library. Below is an abstract and a link to the video.

ABSTRACT

We discuss two proposed language features for inclusion in ECMAScript-Harmony. The first, dynamic proxies, enables Javascript programmers to create proxy objects that can intercept property access, assignment, enumeration, etc. It is a powerful metaprogramming mechanism that provides a standard API for creating generic wrappers for transparent access control, implementing legacy API adaptors, profilers, lazy initialization, etc.

The second part of the talk introduces a traits library for ECMAScript 5. Traits are a more robust alternative to multiple inheritance or mixin-based composition. Based on ECMAScript 5's new "property descriptor" API, we built a portable lightweight library that supports trait-based object composition. We discuss the limitations of introducing traits using a library approach and highlight the benefits of direct support for traits in ECMAScript-Harmony.

Video: www.youtube.com/watch?v=A1R8KGKkDjU Talk slides: es-lab.googlecode.com/files/harmony_highlights_techtalk.pdf traits.js library: www.traitsjs.org

# Faisal Vali (14 years ago)

From: Tom Van Cutsem <tomvc at google.com> To: es-discuss <es-discuss at mozilla.org> Date: Fri, 30 Apr 2010 15:42:26 -0700 Subject: Tech talk on proxies and traits Hi, I recently gave a Google tech talk on my joint work with Mark S. Miller on Harmony proxies and the traits.js library. Below is an abstract and a link to the video.

<snip>

Video: www.youtube.com/watch?v=A1R8KGKkDjU Talk slides: es-lab.googlecode.com/files/harmony_highlights_techtalk.pdf traits.js library: www.traitsjs.org

<snip>

Thanks Tom. I've felt the need for a robust interception mechanism in javascript for years now and was disheartened when I read about interceptors "climbing the meta ladder" in a possibly prohibitive way. Now, as a result of all your hard work I think we'll be getting quite a comprehensive interceptor solution that compromises little. You have my gratitude.

Also, thanks for the excellent talk - it is a clear, simple and well illustrated introduction to Proxies and Traits.

I do have one request for clarification regarding the object 'proto' supplied during proxy creation: (i.e. Proxy.create(handler, proto))

Before a proxy has been fixed, the 'proto' is invisible to all accesses and mutations on proxy (i.e they are all delegated to the handler). Correct?

So It seems to me that the 'proto' object serves only two purposes -

  1. 'proto' is returned when one calls 'Object.getPrototypeOf(proxy)'
  2. When a proxy gets 'fixed', the 'proto' object is made the 'fixed-proxys's prototype - and all subsequent accesses not explicitly handled by the 'fixed-proxy' will be forwarded to the 'proto'

Correct?

Thanks again!

Faisal Vali Radiation Oncology Loyola

# Mark S. Miller (14 years ago)

On Sat, May 1, 2010 at 9:29 AM, Faisal Vali <faisalv at yahoo.com> wrote:

From: Tom Van Cutsem <tomvc at google.com> To: es-discuss <es-discuss at mozilla.org> Date: Fri, 30 Apr 2010 15:42:26 -0700 Subject: Tech talk on proxies and traits Hi, I recently gave a Google tech talk on my joint work with Mark S. Miller on Harmony proxies and the traits.js library. Below is an abstract and a link to the video.

<snip>

Video: www.youtube.com/watch?v=A1R8KGKkDjU Talk slides: es-lab.googlecode.com/files/harmony_highlights_techtalk.pdf traits.js library: www.traitsjs.org

<snip>

Thanks Tom.  I've felt the need for a robust interception mechanism in javascript for years now and was disheartened when I read about interceptors "climbing the meta ladder" in a possibly prohibitive way.  Now, as a result of all your hard work I think we'll be getting quite a comprehensive interceptor solution that compromises little. You have my gratitude.

Also, thanks for the excellent talk - it is a clear, simple and well illustrated introduction to Proxies and Traits.

I do have one request for clarification regarding the object 'proto' supplied during proxy creation: (i.e. Proxy.create(handler, proto))

Before a proxy has been fixed, the 'proto' is invisible to all accesses and mutations on proxy (i.e they are all delegated to the handler). Correct?

So It seems to me that the 'proto' object serves only two purposes -  1) 'proto' is returned when one calls 'Object.getPrototypeOf(proxy)'  2) When a proxy gets 'fixed', the 'proto' object is made the 'fixed-proxys's prototype - and all subsequent accesses not explicitly handled by the 'fixed-proxy' will be forwarded to the 'proto'

Correct?

Hi Failsal,

Yes, these two. And one more thing I can think of:

  1. proxy instanceof Foo uses proxy's proto to determine if proxy is an instance of Foo.
# Mark S. Miller (14 years ago)

On Sat, May 1, 2010 at 9:29 AM, Faisal Vali <faisalv at yahoo.com> wrote:

From: Tom Van Cutsem <tomvc at google.com> To: es-discuss <es-discuss at mozilla.org> Date: Fri, 30 Apr 2010 15:42:26 -0700 Subject: Tech talk on proxies and traits Hi, I recently gave a Google tech talk on my joint work with Mark S. Miller on Harmony proxies and the traits.js library. Below is an abstract and a link to the video.

<snip>

Video: www.youtube.com/watch?v=A1R8KGKkDjU Talk slides: es-lab.googlecode.com/files/harmony_highlights_techtalk.pdf traits.js library: www.traitsjs.org

<snip>

Thanks Tom.  I've felt the need for a robust interception mechanism in javascript for years now and was disheartened when I read about interceptors "climbing the meta ladder" in a possibly prohibitive way.  Now, as a result of all your hard work I think we'll be getting quite a comprehensive interceptor solution that compromises little. You have my gratitude.

Also, thanks for the excellent talk - it is a clear, simple and well illustrated introduction to Proxies and Traits.

I do have one request for clarification regarding the object 'proto' supplied during proxy creation: (i.e. Proxy.create(handler, proto))

Before a proxy has been fixed, the 'proto' is invisible to all accesses and mutations on proxy (i.e they are all delegated to the handler). Correct?

Oh, and yes, this is correct.

# Faisal Vali (14 years ago)

---------- Forwarded message ---------- From: Faisal Vali <faisalv at gmail.com>

To: "Mark S. Miller" <erights at google.com>

Date: Sat, 1 May 2010 14:10:01 -0500 Subject: Re: Tech talk on proxies and traits On Sat, May 1, 2010 at 12:29 PM, Mark S. Miller <erights at google.com> wrote:

On Sat, May 1, 2010 at 9:29 AM, Faisal Vali <faisalv at yahoo.com> wrote: <snip>

I do have one request for clarification regarding the object 'proto' supplied during proxy creation: (i.e. Proxy.create(handler, proto))

Before a proxy has been fixed, the 'proto' is invisible to all accesses and mutations on proxy (i.e they are all delegated to the handler). Correct?

Oh, and yes, this is correct.

So It seems to me that the 'proto' object serves only two purposes -

  1. 'proto' is returned when one calls 'Object.getPrototypeOf(proxy)'
  2. When a proxy gets 'fixed', the 'proto' object is made the 'fixed-proxys's prototype - and all subsequent accesses not explicitly handled by the 'fixed-proxy' will be forwarded to the 'proto'

Yes, these two. And one more thing I can think of: 3) proxy instanceof Foo uses proxy's proto to determine if proxy is an instance of Foo.

Thanks for the clarification Mark.

As I read the proposal, I do wish an invoke-like trap had been accepted - but I understand that there were some technicalities that proved unresolvable.

It might be useful to be able to tell when someone was accessing a property as a function call:

str_proxy.length -vs- str_proxy.length() db_proxy.data -vs- db_proxy.data() -vs- db_proxy.data( { filter : '....' } )

I realize that maintaining the invariant of "o.m(a) is equivalent to var f = o.m; f.call(o,a)" is advisable - but are we certain that it should be mandatory in the setting of proxies (i.e represent a true invariant)? In the world of proxies (or for that matter 'get' accessors in es5) we can't even guarantee that two sequential accesses of the same property will return the same value, object or function. There is convenience to being able to type either proxy.length or proxy.length() and have it do the right thing.

Since I do not have that much experience with interceptors, it is too early for me to say that preventing the 'get' handler from distinguishing whether a property is about to be 'called' is definitely a loss in expressivity. I sense it might be useful to have that feature. A simple solution that would allow maintaining the above mentioned 'invariant' in most cases and allow breaking it when necessary would involve a flag passed into the 'get' handler indicating that the property is about to be 'called'. What would be the negative ramifications of such a solution (asides from the fact that it may get abused - like the 'get' accessor in es5 ;)?

Thanks.

Faisal Vali Radiation Oncology Loyola

# Brendan Eich (14 years ago)

On May 1, 2010, at 12:34 PM, Faisal Vali wrote:

As I read the proposal, I do wish an invoke-like trap had been accepted - but I understand that there were some technicalities that proved unresolvable.

Everyone wants noSuchMethod -- we still support it in
SpiderMonkey, and probably will for a long time.

A simple solution that would allow maintaining the above mentioned 'invariant' in most cases and allow breaking it when necessary would involve a flag passed into the 'get' handler indicating that the property is about to be 'called'. What would be the negative ramifications of such a solution (asides from the fact that it may get abused - like the 'get' accessor in es5 ;)?

This is a good idea. In all practical implementations, callee
expressions are specialized so the "get" can tell it is computing a
callee. This is done to bind |this| in the call expression of which
the callee expression is a left prefix.

Mark and Tom may have thoughts.

# Oliver Hunt (14 years ago)

On May 1, 2010, at 1:27 PM, Brendan Eich wrote:

A simple solution that would allow maintaining the above mentioned 'invariant' in most cases and allow breaking it when necessary would involve a flag passed into the 'get' handler indicating that the property is about to be 'called'. What would be the negative ramifications of such a solution (asides from the fact that it may get abused - like the 'get' accessor in es5 ;)?

This is a good idea. In all practical implementations, callee expressions are specialized so the "get" can tell it is computing a callee. This is done to bind |this| in the call expression of which the callee expression is a left prefix.

[[Get]] in JavaScriptCore does not distinguish the get for a.b vs a.b(), i like to imagine that we count as being a practical implementation ;)

# Mark S. Miller (14 years ago)

[+stay]

On Sat, May 1, 2010 at 12:10 PM, Faisal Vali <faisalv at gmail.com> wrote:

[...]

Thanks for the clarification Mark.

As I read the proposal, I do wish an invoke-like trap had been accepted - but I understand that there were some technicalities that proved unresolvable.

It might be useful to be able to tell when someone was accessing a property as a function call:

str_proxy.length -vs- str_proxy.length() db_proxy.data -vs- db_proxy.data() -vs- db_proxy.data( { filter : '....' } )

I realize that maintaining the invariant of "o.m(a) is equivalent to var f = o.m; f.call(o,a)" is advisable - but are we certain that it should be mandatory in the setting of proxies (i.e represent a true invariant)? In the world of proxies (or for that matter 'get' accessors in es5) we can't even guarantee that two sequential accesses of the same property will return the same value, object or function.

You are correct. This invariant is a pleasant property but not a necessary one. Our first proxies proposal did have an invoke() trap. Although we recognized the invariant breakage as an argument against it, it wasn't a fatal argument. The last straw was instead the sequencing issue Brendan raised: Now that ES5 standardizes getters, in a method call, ES5 is clear that the getter runs before the method arguments are evaluated. For example:

var x = 3;
obj = { get foo() { ++x; return function(n) { return x * n; }; }};
obj.foo(x *= 2);  // should return 64

If the method's arguments were evaluated before the getter were run, the answer would be 42. Although I agree that 42 is the ultimate answer, it is not the answer sanctioned by the ES5 standard. Were the invoke() trap to be triggered instead of the get() trap above, it would only be triggered after the method arguments were evaluated, and so 42 is the only answer it could know to emulate.

The more I have become aware of the costs of this sequencing semantics, the more unfortunate I think it is. Mike Stay (cc'ed) is currently repurposing the Cajita translation framework to create approximately an ES5/strict to ES3R translator we're calling ES5/3. In order to avoid exceeding the 20% overheads currently paid by Cajita for normal property access and method calls, we're going to violate this sequencing and give 42 for this example. (A bit of testing reveals that V8 gives 42 as well. FF and Safari both correctly give 64.)

There is convenience to being able to type either proxy.length or proxy.length() and have it do the right thing.

I think having "x.length()" ever be a synonym for "x.length" in JS is a terrible idea.

Since I do not have that much experience with interceptors, it is too early for me to say that preventing the 'get' handler from distinguishing whether a property is about to be 'called' is definitely a loss in expressivity.  I sense it might be useful to have that feature.  A simple solution that would allow maintaining the above mentioned 'invariant' in most cases and allow breaking it when necessary would involve a flag passed into the 'get' handler indicating that the property is about to be 'called'.  What would be the negative ramifications of such a solution (asides from the fact that it may get abused - like the 'get' accessor in es5 ;)?

Among the many alternatives we've considered, passing such a flag was not among them. I haven't thought about it in any depth yet, but my first reaction is positive. It may solve a number of problems that are otherwise unpleasant; about which more later...

Thanks for the suggestion!

# Mark S. Miller (14 years ago)

On Sat, May 1, 2010 at 1:27 PM, Brendan Eich <brendan at mozilla.com> wrote:

On May 1, 2010, at 12:34 PM, Faisal Vali wrote:

As I read the proposal, I do wish an invoke-like trap had been accepted - but I understand that there were some technicalities that proved unresolvable.

Everyone wants noSuchMethod

I don't. I want proxies instead. ;)

-- we still support it in SpiderMonkey, and probably will for a long time.

A simple solution that would allow maintaining the above mentioned 'invariant' in most cases and allow breaking it when necessary would involve a flag passed into the 'get' handler indicating that the property is about to be 'called'.  What would be the negative ramifications of such a solution (asides from the fact that it may get abused - like the 'get' accessor in es5 ;)?

This is a good idea. In all practical implementations, callee expressions are specialized so the "get" can tell it is computing a callee. This is done to bind |this| in the call expression of which the callee expression is a left prefix.

Mark and Tom may have thoughts.

I just saw Oliver's response. If some major JS implementations cannot provide this additional flag without slowing down normal non-proxy access, then I'd agree we need to drop it. Support for proxies must impose no overhead on access to non-proxies. But if this flag can be provided without additional overhead on non-proxies, I do think it is desirable. It solves a number of problems...

# Dmitry A. Soshnikov (14 years ago)

Hello Mark,

Sunday, May 2, 2010, 1:02:36 AM, you wrote:

On Sat, May 1, 2010 at 1:27 PM, Brendan Eich <brendan at mozilla.com> wrote:

On May 1, 2010, at 12:34 PM, Faisal Vali wrote:

As I read the proposal, I do wish an invoke-like trap had been accepted - but I understand that there were some technicalities that proved unresolvable.

Everyone wants noSuchMethod

I don't. I want proxies instead. ;)

By the way, why exactly proxies? And not special meta hooks such as noSuchMethod, construct, call, get, set and other?

This seems again a bit overloaded, to create first a real object; then to create a proxy for it, and because of we can use the proxy object in all related actions (via hooks get, set, hasOwn, enumerate, fix and other) -- to work after that only with that proxy (and forgot about the original object).

Why does committee dislike the special meta methods directly on objects? It seems useful

let o = { // called for every reading get: function (name) { // },

set: funciton (name, value) { // },

// ability to make an object callable call: funciton (...args) { // },

// only for not found in // the prototype chain noSuchMethod: function (name, args) { var delegate = this.getDelegateFor(name); delegate && delegate.call(this, args); },

noSuchProperty: funciton () { // },

getDelegateFor: function (name) { for (let k = this.delegates.length; k--;) { if (typeof this.delegates[k] == "funciton") return this.delegates[k][name]; } return null; }

// additional prototypes // for delegation this.delegates: [proto1, proto2] };

o.foo(); // noSuchMethod o.bar; // get, noSuchProperty

And so on. Yes, it looks like a full Python's copy, but, isn't it convinient and useful?

Having simple definition, at the same time still there is stratification of "Meta" and "App" levels. Thus, implementation and standard should say that all propertyNames are reserved to be meta.

Dmitry.

# Brendan Eich (14 years ago)

On May 1, 2010, at 1:40 PM, Oliver Hunt wrote:

On May 1, 2010, at 1:27 PM, Brendan Eich wrote:

A simple solution that would allow maintaining the above mentioned 'invariant' in most cases and allow breaking it when necessary would involve a flag passed into the 'get' handler indicating that the property is about to be 'called'. What would be the negative ramifications of such a solution (asides from the fact that it may get abused - like the 'get' accessor in es5 ;)?

This is a good idea. In all practical implementations, callee
expressions are specialized so the "get" can tell it is computing a
callee. This is done to bind |this| in the call expression of which
the callee expression is a left prefix.

[[Get]] in JavaScriptCore does not distinguish the get for a.b vs
a.b(), i like to imagine that we count as being a practical
implementation ;)

My mistake, I thought JSC did. How do you compute |this| for the call?
I mean, |this| binds to whatever |a| evaluated to, and it evaluates
only once, so something differs in how you compile a.b in an
expression such as (x = a.b) or (a.b + c.d) vs. how you compile a.b in
a.b().

# Brendan Eich (14 years ago)

On May 1, 2010, at 2:49 PM, Dmitry A. Soshnikov wrote:

Hello Mark,

Sunday, May 2, 2010, 1:02:36 AM, you wrote:

On Sat, May 1, 2010 at 1:27 PM, Brendan Eich <brendan at mozilla.com>
wrote:

On May 1, 2010, at 12:34 PM, Faisal Vali wrote:

As I read the proposal, I do wish an invoke-like trap had been accepted - but I understand that there were some technicalities
that proved unresolvable.

Everyone wants noSuchMethod

I don't. I want proxies instead. ;)

I meant "Everyone" to mean "many people" -- for the convenience.

By the way, why exactly proxies? And not special meta hooks such as noSuchMethod, construct, call, get, set and other?

Mark and Tom's write-up is on the wiki, have you read it?

Stratifying means native objects need no magic meta methods which can
be hijacked by user code. This is important for the spec's soundness,
as well as for security and ease of implementation/optimization.

Nothing reserved names, that is just a Python convention, and C,
or really the C pre-processor I suppose. The ship has sailed. Even if
we could reserve names, mixing traps and base methods is a recipe
for spec unsoundness, insecurity, and implementation bugs and slowness.

Proxies avoid all these problems. They are truly winning, we have an
implementation nearly done for SpiderMonkey so I can write this as an
implementor.

The only issue that nags at us is the loss of a convenient invoke trap
that preserves evaluation order. One could be added, but it is
tantamount to creating (or hitting a cached) Proxy, in order to
preserve order of evaluation.

# Brendan Eich (14 years ago)

On May 1, 2010, at 2:02 PM, Mark S. Miller wrote:

I just saw Oliver's response.

Hold the phone -- we're not done sorting out how JSC has two results
for a.b in a.b() vs. one result in (a.b * 1). However that works, I
claim it could arrange for a different flag to be passed to the "get"
trap on a for id 'b'.

# Oliver Hunt (14 years ago)

On May 1, 2010, at 3:25 PM, Brendan Eich wrote:

On May 1, 2010, at 1:40 PM, Oliver Hunt wrote:

On May 1, 2010, at 1:27 PM, Brendan Eich wrote:

A simple solution that would allow maintaining the above mentioned 'invariant' in most cases and allow breaking it when necessary would involve a flag passed into the 'get' handler indicating that the property is about to be 'called'. What would be the negative ramifications of such a solution (asides from the fact that it may get abused - like the 'get' accessor in es5 ;)?

This is a good idea. In all practical implementations, callee expressions are specialized so the "get" can tell it is computing a callee. This is done to bind |this| in the call expression of which the callee expression is a left prefix.

[[Get]] in JavaScriptCore does not distinguish the get for a.b vs a.b(), i like to imagine that we count as being a practical implementation ;)

My mistake, I thought JSC did. How do you compute |this| for the call? I mean, |this| binds to whatever |a| evaluated to, and it evaluates only once, so something differs in how you compile a.b in an expression such as (x = a.b) or (a.b + c.d) vs. how you compile a.b in a.b().

We copy |this| in advance. For reference here is the bytecode representation for the function: function f(){ var a; a.b; } 3 m_instructions; 1 parameter(s); 2 callee register(s) [ 0] enter [ 1] get_by_id r1, r0, b(@id0) [ 9] ret undefined(@k0)

(I'm assuming this is sufficiently obvious to not require any real explanation)

Here's function f() { var a; a.b(); } 5 m_instructions; 1 parameter(s); 11 callee register(s)

[ 0] enter [ 1] mov r2, r0 copy the variable a from r0 to r2 [ 4] get_by_id r1, r2, b(@id0) resolve a.b -> r1 [ 12] call r1, r1, 1, 11 Call r1 -- this will be in r2, the instruction arguments are somewhat "interesting" so i won't go into details as to what they mean [ 17] ret undefined(@k0)

As you can see there's no difference between how we do the property resolution for an ordinary lookup vs. a function call.

# Brendan Eich (14 years ago)

On May 1, 2010, at 3:46 PM, Oliver Hunt wrote:

As you can see there's no difference between how we do the property
resolution for an ordinary lookup vs. a function call.

Thanks -- very helpful.

This shows that Faisal's flag idea is not something implementations
gain automatically by optimizing away Reference internal types (from
the ES specs), as I had hoped at first. So we are out of luck adding
it without adding some runtime overhead. This seems like a fatal flaw.

# Kris Kowal (14 years ago)

On Fri, Apr 30, 2010 at 3:42 PM, Tom Van Cutsem <tomvc at google.com> wrote:

Hi, I recently gave a Google tech talk on my joint work with Mark S. Miller on Harmony proxies and the traits.js library. Below is an abstract and a link to the video.

May I recommend that the "enumerate" method return a "forEach"-able object, such that:

for (x in proxy) …

be reified as:

handler.enumerate().forEach(…)

albeit optimized for proper Arrays?

This would permit at least some degree of laziness.

I've also been working on a "handler" API for promises in CommonJS, which has a reasonable degree of symmetry. One thing that's occurring to me is that it is probably desirable for a generic, potentially frozen prototype handler to be exposed so that they can be explicitly prototypically inherited and extended. I'm not sure whether you've specified that handlers must be records, owning all usable trap properties, but that would preclude meta-object hierarchies. I suspect that these will be desirable and that exposing the base handler prototype would be useful.

Kris Kowal

# Brendan Eich (14 years ago)

On May 1, 2010, at 4:29 PM, Kris Kowal wrote:

On Fri, Apr 30, 2010 at 3:42 PM, Tom Van Cutsem <tomvc at google.com>
wrote:

Hi, I recently gave a Google tech talk on my joint work with Mark S.
Miller on Harmony proxies and the traits.js library. Below is an abstract and
a link to the video.

May I recommend that the "enumerate" method return a "forEach"-able object, such that:

for (x in proxy) …

be reified as:

handler.enumerate().forEach(…)

albeit optimized for proper Arrays?

This would permit at least some degree of laziness.

See harmony:proxies --
specifically these bulleted items near the bottom:

  • Should ES-harmony support a general iterator or generator mechanism,
    the interface of the enumerate trap should be aligned with that
    mechanism. . . .

  • Waldemar raised objections against the current Proxy API to proxy
    objects with a large number of properties. The problematic traps are
    fix and enumerate. W.r.t enumerate, a proxy could return a proxy for
    an array. Additionally, enumerate should be modified as soon as there
    is a solid proposal for generators/iterators. Proxies for large
    objects could resist being fixed. This solution is satisfactory as
    long as no part of the spec depends on an object being non-extensible/ sealed/frozen.

Dave Herman and I have a generators/iterators proposal coming along --
should be up some time next week on the wiki.

I've also been working on a "handler" API for promises in CommonJS, which has a reasonable degree of symmetry. One thing that's occurring to me is that it is probably desirable for a generic, potentially frozen prototype handler to be exposed so that they can be explicitly prototypically inherited and extended. I'm not sure whether you've specified that handlers must be records, owning all usable trap properties, but that would preclude meta-object hierarchies. I suspect that these will be desirable and that exposing the base handler prototype would be useful.

Not to worry, traps are accessed as handler properties, not "own",
just "in" (so possibly in a prototype). See harmony:proxies_semantics . Example:

[[Get]] (P) When the [[Get]] internal method of a trapping proxy O is called with
property name P, the following steps are taken:

1. Let handler be the value of the [[Handler]] internal property of O.
2. Let get be the result of calling the [[Get]] internal method of  

handler with argument “get”. 3. If get is undefined, throw a TypeError. 4. If IsCallable(get) is false, throw a TypeError exception. 5. Return the result of calling the [[Call]] internal method of get
providing handler as the this value, O as the first argument and P as
the second argument.

Mozilla's implementation (see bugzilla.mozilla.org/show_bug.cgi?id=546590) already includes a no-op handler. We envision others that can be
reused and delegated to via prototypes.

# Kris Kowal (14 years ago)

On Sat, May 1, 2010 at 6:25 PM, Brendan Eich <brendan at mozilla.com> wrote:

W.r.t enumerate, a proxy could return a proxy for an array.

Would be satisfactory if the reification re-checked the length on each iteration.

Additionally, enumerate should be modified as soon as there is a solid proposal for generators/iterators.

Yeah, I caught that in the preso. Sounds good to me.

Dave Herman and I have a generators/iterators proposal coming along -- should be up some time next week on the wiki.

Excellent.

Not to worry, traps are accessed as handler properties, not "own", just "in" (so possibly in a prototype). See harmony:proxies_semantics. Example:

Excellent.

Mozilla's implementation (see bugzilla.mozilla.org/show_bug.cgi?id=546590) already includes a no-op handler. We envision others that can be reused and delegated to via prototypes.

I see, in the unit test, makeNoopHandler. My suggestion was that this should be exposed as part of the API as a base type, but on further reflection, the behaviors of the noopHandler are implied by the non-existence of properties on the handler.

This is all excellent and I'm really glad it's getting such deeply detailed attention. Thanks.

Kris Kowal

# Dmitry A. Soshnikov (14 years ago)

On 02.05.2010 2:33, Brendan Eich wrote:

Stratifying means native objects need no magic meta methods which can be hijacked by user code. This is important for the spec's soundness, as well as for security and ease of implementation/optimization.

Yep, I see that optimization means that in case if that magic hooks would be directly on object that will slow properties/methods resolution and handling in general. With proxies it is possible to work with original object separately and directly. Just one thing seems as an overhead. If a user defines some magic hooks on object, that means (in general) he wants to work with these hooks. And in case of proxies, he should work of course with a new proxy, and (maybe) even to forget about the original object. From this viewpoint the original object seems is not needed any more (besides of course using it inside the proxy's handler), i.e. interaction is unilateral -- from proxy to the original object. But not vice versa. Although, of course some new/modified properties directly on the original object will be reflected in proxy on getting.

Nothing reserved names, that is just a Python convention, and C, or really the C pre-processor I suppose. The ship has sailed. Even if we could reserve names, mixing traps and base methods is a recipe for spec unsoundness, insecurity, and implementation bugs and slowness.

Yep, slowness goes without saying. So, Python can be named as just a "big security hole" then from this viewpoint, I guess?

Proxies avoid all these problems. They are truly winning, we have an implementation nearly done for SpiderMonkey so I can write this as an implementor.

Yep, proxies seems interesting (considering security and slowness issues related with direct names). Is it possible to test them in nightly builds of Firefox? I saw in strawman/harmony examples this construction:

<script type="harmony">

Can it be used already now in nightly builds or it's still just a proposal for versioning/typing scripts?

Dmitry.