extends keyword instead of <superclass ... >
Dmitry A. Soshnikov
dmitry.soshnikov at gmail.com
Tue Mar 29 07:27:04 PDT 2011
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.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20110329/b652e172/attachment-0001.html>
More information about the es-discuss
mailing list