Besides. I'd like to propose also :: syntax (can it break LL handwritten
parsers?) to improve monkey-patching of the dynamic classes. It uses in
C++ and also in Coffee as a sugar for "prototype" property.
Point::create = function () {
...
};
desugars into:
Point.prototype.create = function () {
...
};
Though, I don't see how to define a property on the "class's prototype".
Only with involving "prototype" property:
Object.defineProperty(Point.prototype, "create", {
value: function () {
...
},
enumerable: false
});
Or. To provide the `Class` meta-class which will be able to create
classes at runtime (as expressions) and additionally:
Class.defineInstanceProperty(Point, "create", { ... })
which desugars again into:
Object.defineProperty(Point.prototype, "create", { ... })
and probably Class.defineStaticProperty(Point, "instances", { ... })
which maybe is overhead as can be achieved with
Object.defineProperty(Point, "instances", { ... });
However, I'm not sure about Class.create(...) since it backs us to a
simple wrapper-function used in many libraries providing programming
with classes. Though, class expression can be useful:
let Foo = isDebug
? class Foo {
...
}
: class Foo {
...
}
P.S.:
Let myself to repeat it again, whatever syntax will be chosen (whether
with `extends` or not), I just want it to be _really a sugar_. In other
case there will be no any sense because every library can provide
classes sugar itself. And these "class method", "class method", "class
method" aren't sugar at all. I consider <meta properties ... > also as
not so sugared and still thing that # or @ (if not for `this`) are
better (this includes Brendan's proposal with the spread).
Dmitry.
On 29.03.2011 11:14, Dmitry A. Soshnikov wrote:
On 29.03.2011 2:51, Allen Wirfs-Brock wrote:
On Mar 28, 2011, at 1:53 PM, Dmitry A. Soshnikov wrote:
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).
To quote the title of a famous paper by William Cook: "Inheritance Is
Not Subtyping". This is commonly misquoted as "Subclassing is not
Subtyping".
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.
And quoting the definition of class in /Smalltalk-80: The Langauge
and Its Implementation/: "class: A description of a group of similar
objects". I would emphasize the word "description" in the
Smalltalk-80 definition. In dynamic object oriented languages, a
class consists of the description of the common implementation of a
set of identically implemented objects. Part of that common
implementation may be obtained via inheritance. But obtaining parts
of an object's implementation via inheritance (subclassing) is not
the same as subtyping.
Subtyping implies a substitutive relationship. If B is a subtype of
A, then in general you can expect to be able to substitute B in any
situation where A is expected. Static object oriented languages in
the style of C++, Java, and C# fairly strongly equate subclassing
with subtyping. What you can say in a class definition is
constrained by the rules of subtyping. Dynamic object-oriented
languages such as Smalltalk, Ruby, and Python do not equate
subclassing and subtyping. In such languages, B being a subclass of
A means that B shares some of it implementation with A but it does
not mean that B can always be substituted for A
Allen, all this is correct, though I guess we understand that we talk
about not subtyping as substitution principle (by Liskov), but about
the _sugar for generation of objects with the same structure_ -- to
improve code reuse.
Regarding classes in general I have the following table of "classes"
kinds:
| first-class | second-class (or
"first-order")
--------|-------------------------------
|-----------------------------------
dynamic | Ruby, Python, JS, Coffee | ?
static | freeze(class) | C++, Java
Thus, combination of "statics + second-class" can give us an immutable
type with strong predefined behavior and set of properties.
In dynamic classes first-class classes, a "type" as a set of
predefined and immutable things is not so important. Moreover, for
feature-testing, as a "type-tag" or better to say as a
"classification-tag" can be used just a simple property of an object
which helps to distinguish an object of yours classification from the
object with the same state.
foo.class == Foo; // true -- testing with a class-tag
foo instanceof Foo; // true
It's enough for dynamic first-class classes, and substitution
principle may not be so important. Moreover, even here, e.g. the
following substitution works fine:
bar instanceof Bar; // true
bar instanceof Foo; // true, assuming that Bar is a subclass of Foo
And the set of methods and properties in the dynamic classes of course
can vary over the time. And of course in such a system we cannot
predict whether will be able to substitute an instance after some
mutations (removing/addition methods, etc). But repeat, it's not so
required hard in the dynamic system. But if you still want be sure,
the just make them completely frozen (i.e. static classes) and then
you can be sure.
So what is more important here (and exactly about it is your strawman
as I understand, right?) is the syntactic sugar for exactly
_convenient classified programming_. For the convinient classified
generation of objects created by the specified (classified)
_patterns_. And exactly from the _convenience of the usage_ of such a
sugar I think we should start.
One of the rules of object subtyping is that additional methods may
be added by a subtype but methods may not be deleted. Thus in a
subclassing==subtyping language it is easy to think about subclasses
as generally "extending" superclasses with additional members. The
use of "extends" in Java is no doubt a reflection of that perspective.
Yes, that's true, but it seems a little bit as a nit-picking to exact
syntax/terminology. Instead, we should concentrate on exactly the
_convenient code reuse_ and _convenient classified generation_.
Repeat, it doesn't matter much in dynamic system whether we'll remove
some method (and therefore we shouldn't use keyword "extends"). If you
just don't like exactly this keyword (assuming statics and only
extension, not modification of descendant classes) then we may use any
other word which you think fits better. E.g. `inherits` -- class B
inherits A. Or symbols -- yours, proposed on Twitter (C++'s actually)
colon : -- class B : A. Or Ruby's one -- class B < A (which is also
logical -- "the class B is less than A").
But I think exact keyword isn't so important in this case. `extends`
keyword is just familiar -- yes, from Java's syntax (actually
JavaScript uses Java's syntax). And it doesn't matter and a Java
programmer doesn't know that a class in JS can be dynamic and that
after the extension there can be other modifications.
It is fairly straight forwards to augment JavaScript with the concept
of "class" as a syntactic unit that describes the shared description
of the implementation shared by a group of objects. It would also be
straight forward to including the concept of implementation
"subclassing" in the Smalltalk/Ruby/Python style. It would be very
difficult to introduce the concept of classes as nominal types with
subclassing into the JavaScript.
We haven't here strong types system. So repeat, I see classes
syntactic sugar as just exactly the sugar for the improved classified
programming. Without sugar, JS already has classes. And moreover, many
libraries provide this sugar via wrapper-functions (to just
encapsulate all boring actions by linking prototypes to provide
inheritance, etc). So it's good just to have this sugar directly from
the box.
Using "extends" to mean "subclass of" may be familiar to Java
programers, but it may also be misleading.
We should go from the convenience of the code reuse and code writing.
Not from some other ideologies with nit-picking to keywords.
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.
this second usage of replacing this with @ seems like a separable
piece and the same familiarity argument that might be made for using
"extends" would argue against replacing "this" with "@".
What I want is to provide more convenient programming. What exactly
you don't like in `@` as `this`? Isn't it convenient to describe class
methods as just " (1) `this` evaluated in the class body -- is the
class. (2) `this` evaluated inside instance method -- is an instance".
And do you think the sugar I described is a good declarative form of
classes sugar (or if not -- what did I do wrong?) ?
Writing every time "class method", "class method", "class method" not
only too long (and therefore boring), but also will highlight this
`class` keyword many times (which will annoy the users).
So I think (again) -- what we need from the sugar of classes in JS, is
that it should be _exactly the sugar_. It should convince the
programming, but not provide some syntactically big constructions.
Dmitry.
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss