extends keyword instead of <superclass ... >

Dmitry A. Soshnikov dmitry.soshnikov at gmail.com
Tue Mar 29 00:14:22 PDT 2011


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/90d4a012/attachment-0001.html>


More information about the es-discuss mailing list