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