Yet another class declaration proposal

# Axel Rauschmayer (14 years ago)

FWIW: I’ve picked what I like from the various proposals.

gist.github.com/1336846

# Jake Verbaten (14 years ago)

I like this one mainly for the line

class declarations and object literals should have the same features

However if they have the same features then why bother with class at all.

Why not just have

let Monster = Being <| { ... }

This way we don't introduce the class keyword which is confusing and loaded with assumptions about what it does and means.

# Axel Rauschmayer (14 years ago)

I agree 100%. I still hope that object exemplars will become part of the language. However they are introducing a completely new way of implementing types (or rather, of naming exemplars). That is bound to be a deal-breaker for many. Thus, if I can’t have object exemplars, I’ll settle for the second-best thing: class declarations that look and feel just like them.

Axel

# Allen Wirfs-Brock (14 years ago)

+1,000,000

Minor quibbles

get rid of [incAge]: ... just make it @incAge

we don't need both [propname] and @propname in property declarations and @propname has a narrower meaning (which is good). Also, I don't want to unnecessarily couple object/class declaration syntax with [ ] semantics.

You don't show other at foo but we need it. I would prefer it to be written as other. at foo

You don't show it, but I would be fine with @foo as an abreavation for this at foo but if it is available we could probably get away with requiring this. at foo

I know this will be controversial, but I would prefer only having the expression form. The reason is that

let Monster = Being <| mylib.mixin(Evil, Scary) <| class {...}

is an important usecase and it is harder to make the syntax work with a pure class declaration.

# Axel Rauschmayer (14 years ago)

I’ve updated the gist with (most of) your suggestions and rationales for the decisions.

Minor quibbles

get rid of [incAge]: ... just make it @incAge

we don't need both [propname] and @propname in property declarations and @propname has a narrower meaning (which is good). Also, I don't want to unnecessarily couple object/class declaration syntax with [ ] semantics.

You don't show other at foo but we need it. I would prefer it to be written as other. at foo

You don't show it, but I would be fine with @foo as an abreavation for this at foo but if it is available we could probably get away with requiring this. at foo

I know this will be controversial, but I would prefer only having the expression form. The reason is that

let Monster = Being <| mylib.mixin(Evil, Scary) <| class {...}

is an important usecase and it is harder to make the syntax work with a pure class declaration.

Fine with me, I don’t have any preference in this regard.

# Russell Leggett (14 years ago)

I know this will be controversial, but I would prefer only having the expression form. The reason is that

let Monster = Being <| mylib.mixin(Evil, Scary) <| class {...}

is an important usecase and it is harder to make the syntax work with a pure class declaration.

I'm not sure if you saw my proposal gist.github.com/1332028 (its a little long, I apologize), but it is very similar to this except instead of unifying class extends and <| by using <| for classes, I went the other way. I did this because people don't really seem to like <| syntactically.

What I wanted to bring up here, though, is your desire for:

let Monster = Being <| mylib.mixin(Evil, Scary) <| class {...}

which is something I suggested in my own proposal (more or less). However, this example, as much as I like it, clearly breaks rule of only allowing literals on the RHS of <|. I would like to break that rule as well, and I was curious how you proposed to solve it. What is your opinion of my proposed solution:

// I propose a new form of object wrapper that holds an object and a reference to another object // that will act as that object's prototype. This would be strictly non-destructive, but allow it to // be used in place of the original object.

// lets start with a <| example function customExtend(parent, child){ //some special modification to child goes here return parent <| child; } // or my proposed form function customExtend(parent, child){ //some special modification to child goes here return extends parent child; }

// This would not currently work with <| and for good reason. // With the current semantics, setting the proto for child // could be a BAD thing, and certainly would not work with my intended // semantics for traits/mixins

// My idea is that instead of directly modifying child's proto, something like a special // purpose direct proxy were used instead, where all method calls pass through to the wrapped object, // but any references to the prototype, or going up the prototype chain would instead be delegated // to the wrapper's specified prototype instead. This would also be what calls to super would refer to, // as the two are directly related.

// I'm not sure if this would be easy to make efficient. My gut says it would be more efficient than // copying object properties, and certainly seems like it would alleviate the concerns of things like // copying private members. It would also ensure that in the mixin example, changes to the mixin would // be reflected in the child. Not sure if that is a good thing, but its consistent with prototypal // inheritance.

// In the common case of a literal RHS, this wrapper could be elided, and therefore create no // additional overhead.