Russell Leggett wrote:
On Wed, Aug 8, 2012 at 12:35 PM, Brendan Eich <[email protected]
<mailto:[email protected]>> wrote:
Erik Corry wrote:
Hi
This proposal offers a way to get around some of the strange
semantics
of '=', specifically the way read-only properties and setters on
objects in the prototype chain can restrict what you can do on the
receiver of an assignment.
This is "strange" only insofar as you can't say what you mean if
you want to override. There's no law of nature requiring = to
override, though.
I actually think that the behavior of = makes total sense in regards
to setters and read-only properties. If that was not the behavior, it
would be pretty silly. If = on a setter overrode the setter, it would
defeat the point of the setter. Same with read-only properties.
To be fair, the issue is not overridng "own" read-only or setter-based
properties. It is overriding delegated properties.
But there too one can argue, and extant code wants (see WebIDL),
assignment-invoking-a-setter to abstract over prototype delegation.
That's enough for me to want non-writable assignment failure to match.
Others disagree, but I think they're doing so out of pragmatism more
than principle (the Caja/SES frozen built-in prototypes problem).
Pragmatism is fine, but for the long run I think we are better off
providing both assign and define "screwdrivers" (to use Kevin Smith's
metaphor). Then in principle everyone wins. There's still a hard case
for Caja on older browsers, but that's (a) temporary; (b) solvable at
some cost (as Mark et al. cleverly have indeed solved it).
So I think the long-run right answer, given the sunk cost non-fallacy of
Caja having to deal with most browsers in the field rejecting write
attempts that would shadow a non-writable proto-property, is to level
the field: = and :=, Object.assign and Object.define if appropriate. I'm
not sure batch assignment pays for itself, but we can check on Dart's
experience and user-test and argue that one separately.
Assigning != defining in ES5, even in reality in fixed
implementations of ES3, and in truth going back to the first JS
implementation: proto-setters (internal, hidden) are invoked by
assignment, readonly proto-props prevent = being used to override
on a delegating object (silent failure, of course, due to lack of
try/catch).
What I'm getting at: is assignment != defining strange, or is the
lack of expressiveness that left JS with = but not := strange, or
is = not defining strange? I didn't want to assume the last was
what you meant, since it is not obvious and not the only possible
strangeness or asymmetry.
I think the problem is really the conflation of = depending on the
context. In more classical languages, there is a separation between
methods and data. Overriding would never be done with =. If it was
data, it would set the value of the field for that instance, and if it
was defining a method, that would typically be done as an extension. I
think that a happy path for users could aid in untangling the
confusion, but I think we have to be clear about what that happy path
should be.
It's hard to disagree :-).
However it has some strangeness itself:
* There is little point in having read-only properties if the
common
way to do assignment is :=. := will just walk all over a
read-only
property.
No, readonly properties must be {writable: false, configurable:
false} to have integrity, and := cannot redefine a
non-configurable property.
This brings me to an important point. I think we are conflating too
much the ease of definition with the intent of Object.extend. Allen's
strawman actually says := is similar in intent but not semantics. I
don't like that, and I think it adds to the confusion. I think we have
three cases here.
Oh, I agree completely if the topic is Object.extend -- which is a
well-know library method that uses assignment, not any ES5-only
Object.defineProperty API.
1. You would like to mixin additional behaviors. This is commonly
done with something like Object.extend, but that typically relies
on [Put] semantics, but we really would like those to be defined.
Mixins are available in many languages in various forms. There are
many implementations for doing them in JavaScript and they are
fairly commonly used. Mixins typically involve a group of methods
which should always be mixed in together. Making super work
correctly here is important.
Agreed, mixins are a use-case to serve, not necessarily by anything we
are currently discussing.
I disagree that Object.extend does "mixins" if the methods should always
be mixed in together. It may be that when using PrototypeJS in the past,
you could get away with using Object.extend this way. With ES5 you
can't. See http://traitsjs.org/ for an ES5-based approach that enforces
all-or-none-with-throw and other mixin properties.
Given the ability to specify non-configurability along with
non-writability in ES5, := can be used for high-integrity mixins.
1. You would like to define a single property using a similar style
as =, but you want to make sure it is a definition instead of a put.
Object.defineProperty, but it's verbose and := seems a strict
improvement to me.
1. You have several values that you would like to [Put] - basically
just a batch assignment.
I believe that := is ill suited to straightening out these cases.
See above. I think your (1) is ill-defined, but for high-integrity cases
you seem to want ("should always be mixed in together"), ES5 and any
sugar such as := do help. For (2), := helps because there's no shorter
way to specify attributes.
I think it will commonly be needed for #3, but instead do definition.
Its convenience lends itself to abuse.
I doubt this. Arguments of the "developers will use it wrong" need
evidence, and developers are smart. They learn.
/be
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss