Andreas forwarded me this message as he is currently busy with his day job.
---------- Forwarded message ----------
From: *Brendan Eich* <[email protected] <mailto:[email protected]>>
Date: 2013/12/4
Subject: Re: [JS-internals] Transparency of JavaScript Proxies
To: [email protected] <mailto:[email protected]>,
[email protected] <mailto:[email protected]>
Cc: [email protected]
<mailto:[email protected]>
[email protected] <mailto:[email protected]> wrote:
There are two important differences between Racket's design and
the JS design. One is that Racket started with two notions of
equality, one of which was_not_ pointer equality. Perhaps `==`
could fill this role for proxies, but I highly doubt it.
'==' in JS has always been reference equality for two objects.
The second was that because Racket features pre-emptive
concurrency, which JS does not,
Right!
some of the invariants that you'd lose by having two `equal?`
data structures behave differently are already lost (in the case
of mutable data).
I didn't see a compelling example (the function f(x, y) { return (x
=== y) ? "something" : y.foo; } example was contrived), but one that
wants structural at-this-moment equality of the Racket 'equal?' kind
can be written in JS (using an ES6 WeakMap memo to traverse object
graphs without cycling forever or visiting multiple connected
subgraphs more than once).
Sure, it's a contrived example to demonstrate a problem in a very simple
and isolated way.
For a parallel discussion on the same topic with Mark Miller, I am
working on a better example, which I'll be copying to you as soon as
it's finished later today.
The code that wants contracts to be transparent for such an operation
will have to provide that operation as a function.
That was our first thought, too, but it breaks some important use cases
that arise in program maintenance and development.
1. Contracts implemented using proxies. Adding a contract to a program
should never change the semantics of contract-abiding code - if the
contract is violated, it is of course fine to crash. Also, adding a
contract to a program should not force you to change something else in
your program: a very useful pattern is to impose a contract on code
loaded at run time, say, a mashup. In this case, it is very cumbersome
to patch up this code to use a different equalp (intercept the load,
parse everything, rewrite the parse tree, etc) and it has to be done for
eval, too.
2. Monitoring implemented using proxies. Here, you'd use the proxy to
record all gets and sets applied to an object, for example, to create a
replayable mock object. Again, adding monitoring should not change the
meaning of the program and you should not be forced to change the code.
In no case do I see JS == or === changing, in ECMA-262 or in an
accepted patch to SpiderMonkey.
No existing code would be broken by the change that we are proposing.
Even code with proxies will work the same as before. == and === for
objects will be slightly slower: we are going to evaluate by how much
and how it impacts overall performance. [we were thinking of using
JSBench for the evaluation, but any suggestion would be welcome]
Andreas, can you not proceed without hacking either one engine or the
standard, by writing such a function equalp(x, y) {...} yourself and
using it?
This is a research project, where we want to investigate the semantics
of proxy equality in response to a perceived need by us and also by
others (Wadler, Siek, the Racket designers).
For a proper evaluation, we need to implement it in the engine,
otherwise we'd be comparing apples with pears.
A separate equalp would not cut it for us, as explained above.
Implementing it in JS, as you seem to suggest, would impose a burden on
applications that require transparent proxy equality.
However, we could provide a built-in equalp as a by-product of our
efforts, if that is of interest.
-Peter
/be
_______________________________________________
dev-tech-js-engine-internals mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-tech-js-engine-internals