On 28.03.2011 0:05, Brendan Eich wrote:
On Mar 27, 2011, at 11:33 AM, Juan Ignacio Dopazo wrote:
On Sat, Mar 26, 2011 at 6:31 PM, Dmitry A. Soshnikov
<[email protected] <mailto:[email protected]>> wrote:
Why not just to use already reserved `extends` keyword for
specifying a superclass? These XML-like braces looks not so elegant.
I asked this question a couple of days ago. The answer is quite
simple. Object initializer extensions are more than just constructor
syntax. They allow you to create complex objects without all
the hassle in (function(){}()). So the constructor syntax was made
this way to be consistent with object initializer syntax.
The meta syntax (e.g., var obj = {<proto: p>, key: val}) is not
inconsistent with initialisers, it's an extension to them. But it's
not the only self-consistent extension. Dmitry mentioned letting the
meta properties appear to be regular key: value pairs but
distinguishing the keys with @ or #.
Allen makes the point that class D extends B {...} may look too much
like languages where it means something quite different. That's true,
but I am not sure JS should be so special that it seems to mix bits of
those languages into one (of several conceivable) extensions to
initialiser syntax:
class D {<superclass B>};
Whatever you think of the meta section, the leading 'class D {'
telegraphs influence from, and just familiarity with, those other
languages. And I don't think that is a bad thing even if semantics differ.
Just changing 'class' to 'constructor' (adding a new
perhaps-only-contextually reserved word, and a long one at that) is
not the issue. Sure, doing that would in a text-only way make the
syntax not look like any other language, exactly. But ignore the skin:
the bones look familiar, going back to C structs.
Now add some notion of inheritance and you're following the C++ "body
plan".
Exactly. "Classes" are not about just the "class" keyword, but about the
_ability to classify_, i.e. to program in classified (i.e. with
object-patterned programming). JS supports (and supported all these
years both approaches: delegation-based prototypal (i.e. unclassified or
chaotic code reuse) and classical (classified or systematized code reuse).
Thus, a "class" in JS is a pair of "constructor function + prototype".
From this viewpoint, e.g. classes in Python (or CoffeeScript) are just
syntactic sugar of the same delegation-based inheritance used in JS. And
this means that JS also may have this sugar -- to allow users to program
in classified manner (if they need to). So there's no a big difference
between these languages and therefore keyword `extends` may fit
absolutely normally.
Here how I see classes syntactic in JS (a combination of Coffee's sugar
+ Java's syntax, since we can't eliminate it).
Notes:
I think that usage of thing like: class method fromString() { .. } are
to verbose.
Don't think we need another keyword `method` at all.
Also I used a syntactic sugar for `this` keyword as `@`. This `at`
allows easily to define and distinguish class- and instance- methods.
The rule is simple: if a property/method inside the class body starts
with @ -- it's the class's property/method (i.e. `this` refers to
class). In other case -- it's an instance method. @ evaluated inside the
instance method refers of course to the instance.
Here's a small example with sugared (on the left hand) and desugared (on
the right hand side) views: http://bit.ly/hvS7hl Take a look please.
And below is just an example without the desugaring. Thus, the definiton
itself is in declarative form. Also I think it's good to provide both
dynamic and static classes. By default I used dynamic classes, so
`static` keyword is explicit.
In the example I also used `include` keyword as an ability to mixin some
module as a direct ancestor of an instance, i.e. before the class in the
hierarchy. Mixins/traits will allow to reuse the code horizontally (not
only with a single vertical inheritance "tower").
/* ------------------------------------------------------
* Class Point definition
* ------------------------------------------------------
*/
class Point {
/**
* Class method (placed on constructor function)
*/
@fromString: function (s) {
return new Point(parse(s));
}
/**
* Instance intializer (aka "constructor")
*/
initialize: function (x, y) {
@move(x, y);
}
/**
* Simple instance method (placed on prototype)
*/
move: function (x, y) {
@x = x;
@y = y;
@repaint();
}
/**
* Class property (placed on constructor function)
*/
@x: 10
}
/* ------------------------------------------------------
* Class Point3D definition
* ------------------------------------------------------
*/
static class Point3D extends Point {
include Comparable;
/**
* Class static property
*/
@instances: []
/**
* Instance intializer (aka "constructor")
*/
initialize: function (x, y, z) {
super(x, y);
@z = z;
@class.instances.push(@); // save the instance
}
}
/* ------------------------------------------------------
* Examples:
* ------------------------------------------------------
*/
// create new 3D point
let point = new 3DPoint(10, 20, 30);
console.log(point); // "[instance 0x1382 of Point3D class]"
// inherited method
point.move(100, 200);
// introspect the class
console.log(point.class); // "[class Point3D]"
console.log(point.class === Point3D); // true
// instrospect the super class
console.log(point.class.super); // "[class Point]"
console.log(point.class.super === Point); // true
console.log(Point3D.super === Point); // true
console.log(point instanceof Point3D); // true
console.log(point instanceof Point); // true
// class method
let p = Point.fromString("10-20");
console.log(p.class); // "[class Point]"
// analyze class methods and properties
console.log(Point.classMethods); // ["fromString"]
console.log(Point.classProperties); // ["x"]
console.log(Point.instanceMethods); // ["move"]
console.log(Point3D.classProperties); // ["instances"]
How does it look like? Do we need such a sugar? For both -- classes and
`this` as `@`? Then # can be used for meta-properties on initialisers.
Dmitry.
Do we really need to look different yet still have bones that look so
familiar? I am not convinced.
The strongest case for extending initialiser syntax is that it is
"nearly declarative" today. That suggests strongly making the
extension fully declarative, i.e., not usable as an expression. And
that, all else equal (never is, but:) says to consider class D extends
B {...}. My 2 cents.
/be
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss