On 01.11.2011 17:53, Jeremy Ashkenas wrote:
This doesn't sound right to me. What happens if you call the same
method on another object while the super-resolution is still
active for the first call? IOW, this sounds like it has similar
problems to dynamic scope; the behavior of a function becomes
sensitive to the context in which it's called, which is unmodular.
The problem isn't so much whether it's possible to come up with a
semantics by changing the runtime; I'm sure we could do that. The
problem is finding a way to get the semantics you want without
taxing the performance all other function calls in the language.
(Also known as a "pay-as-you-go" feature: if you don't use the
feature, it shouldn't cost you anything.) We don't know how to do
that for super().
I think one piece of this is worth reiterating: As long as JS.next
classes are mostly sugar for prototypes, and prototypes aren't going
to be deprecated or removed in the next version of JavaScript (two
propositions that I think most of us can get behind) ... then it's
very important that super() and new class syntax *aren't* coupled. An
ES6 super() that fails to work at all with regular prototypes would be
a serious problem. It would make interoperating between vanilla
prototypes and prototypes-built-by-classes much more difficult than
necessary, and the feel of the language as a whole much more fragmented.
If you agree, then a super() that resolves dynamically is the way
forward, and things get easier: super() can be added without classes,
classes can be added without super(), and if both make it in, both can
work seamlessly together.
I don't think that an efficient, pay-as-you-go dynamic super() will be
easy, but with the technical chops of TC39 at your disposal, it should
be possible. Expanding the rough sketch from earlier messages:
* If a function doesn't use super(), there is no cost, and no change
in semantics.
* The first-level super() call is easy, just use the method of the
same name on the __proto__.
* When passing into a super(), add a record to the call stack that
contains [the current object, the name of the method, and the next
level __proto__].
* When returning from a super(), pop the record from the call stack.
* When making a super() call, check the call stack for a record
about the current object and method name, and use the provided
__proto__ instead of this.__proto__ if one exists.
If Dave (and you) is talking about the problem of i-looping at resolving
deeper than 2nd level super-calls, then even call-stack is not needed.
See this implementation: https://gist.github.com/1330574#L68 (with
delete-restore the parent link technique).
Usage level with examples (line 95): https://gist.github.com/1330574#L95
P.S.: I noticed several times here that this --
https://gist.github.com/1327580 -- is *too* cryptic. And if we don't
want to turn JS *again* (well, after it has been explained in more-less
deeper details) into "the world's most misunderstood language" we should
avoid this cryptic stuff.
I give you "over 9000" points that users more likely will use more
convenient and familiar stuff as in Coffee or Dart for classes. So let's
try (if it's possible at all!) to adopt the sugar from Coffee or the
similar I noticed before --
http://dmitrysoshnikov.com/scheme-on-coffee/class.html (thus, names
"initialize" or "constructor" aren't so essential for me, as well as "@"
vs. "this").
Dmitry.
So I guess in theory I agree it'd be nice if super() and class
could be designed completely orthogonally, but in practice they
affect each other. But at the same time, I think a class syntax
where the body is restricted to be declarative is actually a nice
sweet spot anyway. You can still dynamically create classes just
like always, but the declarative form gives you a sweet and simple
syntax for the most common case.
It's definitely the most common case, but a JavaScript class syntax
that is only able to create instances with a static shape would be
severely limited compared to current prototypes. Many existing
libraries and applications would be unable to switch to such a syntax.
One familiar example off the top of my head is Underscore.js:
http://documentcloud.github.com/underscore/docs/underscore.html#section-127
... particularly the bit about adding all of the functional helpers to
the "wrapper" object's prototype, to make chaining style possible.
On the other hand, with the minimalist class proposal in this thread,
switching this library over to use them would be simple (if not
terribly pretty):
class wrapper _.extend({
constructor: function(obj) {
this._wrapped = obj;
}
}, _)
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss