The class operator: a bridge between object and function exemplers

Brendan Eich brendan at mozilla.com
Mon Nov 14 12:28:42 PST 2011


Quick reply to say two things:

1. I like the more radical approach (need to ruminate on it more). Usability remains my concern for classes as sugar (the Cordova edition).

2. Credit to Russell Leggett for posting this idea (I'm pretty sure) as

https://mail.mozilla.org/pipermail/es-discuss/2011-November/017986.html

/be


On Nov 14, 2011, at 12:16 PM, Allen Wirfs-Brock wrote:

> (I'm going to write this up as a strawman, this list gets first shot at it...)
> 
> 
> Introduction
> 
> For ES.next we all want to provide better ways for ES programers to define named abstractions over objects.  One way to do this that we have discussed is "Object exemplars" (http://www.mail-archive.com/es-discuss@mozilla.org/msg10365.html )
> 
> Object exemplars essentially implement the self language style of object abstraction where prototype objects are given names and used as the named abstraction that represents a family of related objects.  Object exemplars typically are instantiated by applying the new operator to a specific named instance of the abstraction.  Object exemplars also typically define an initialization method that is called when a new instance is created.  For the ES implementation of object exemplars, this initialization method is named "constructor".  For example:
> 
> let Point = {
>      x:0,
>      y,0,
>      constructor(x,y} {
>          this.x=x;
>          this.y=y;
>      }
> };
> 
> let p = new Point(1,2);
> 
> Using object exemplars, the named abstraction is itself an instance of the abstraction. Some people seem to be perfect happy to only have and use this form of object abstraction.  However, others prefer to think in a more "classical" style where the named object representing an abstraction is a distinct kind of object that is not itself an instance of the abstraction. In practice, these two views of object abstraction are very closely related/  For example, a very simple addition to the above definition essentially turns Point into a "function exemplar".  Function exemplars can also be thought of as "class exemplars":
> 
> let Point = {
>      x:0,
>      y,0,
>      constructor(x,y} {
>          this.x=x;
>          this.y=y;
>      }
> }.constructor;   //<----------- note added property reference
> 
> let p = new Point(1,2);  //new operator applied to a constructible function 
> 
> However, people that prefer the "classical" style will reasonably point out that it is both easy to forget the trailing property accessor in this definition and that even if it is there a reader is likely to not notice it.
> 
> This proposal provides a solution to these  and other related issues that allow object exemplars and class/function exemplars to have equivalent status and to be  built upon the same underlying syntax and semantic mechanisms.
> 
> The class Operator
> 
> The class operator is used in a new variant of UnaryExpresson:
> 
>    UnaryExpression :
>            class UnaryExpression
>            ...
> 
> The semantics are:
>  1. if UnaryExpression is undefined or null, return the value of UnaryExpression.
>  2. Let obj be ToObject(UnaryExpression)
> 3. Return the result of calling the [[Get]] internal method of obj with argument 'constructor'
> 
> Using the class Operator
> 
> Prefixing an object exemplar with the class operator turns it into a class exemplar:
> 
> let Point = class {
>      x:0,
>      y,0,
>      constructor(x,y} {
>          this.x=x;
>          this.y=y;
>      }
> };
> 
> The precedence of the class operator and the semantics of <| means that it also works as expected with object exemplars that specify an inheritance relationship:
> 
> let Point = class AbstractPoint <| {
>      x:0,
>      y,0,
>      constructor(x,y} {
>          this.x=x;
>          this.y=y;
>      }
> };
> 
> In the above example  Point inherits from AbstractPoint.  If AbstractPoint is a function then this means that the [[Prototype]] of Point is AbstractPoint and that the [[Prototype]] of Point.prototype is AbstractPoint.prototype. If AbstractionPoint is an object exemplar it means that the [[Prototype]] of Point is AbstractPoint.constructor and that the [[Prototype]] of Point.prototype is AbstractPoint.
> 
> 
> The class operator  can prefix any UnaryExpression, not just object literals.  That means that the class operator can be used to classify objects:
> 
> if (class p === Point) ...
> 
> Note that many object-oriented abstraction designers consider this for of class testing to be an anti-pattern. 
> 
> It also works with instances of the standard ES built-in constructors:
> 
> if (class new Array(1,2,3,4) === Array) ... //this will be true
> 
> so are these:
> 
> if (class [1,2,3,4] === Array) ...
> if (class [].pop === Function) ...
> 
> It also works with private value types:
> 
> if (class 1234 === Number && class false === Boolean && class "Hi" === String) ... //all true
> 
> but note that
> 
> if (class null === Object) ... 
> 
> is false.
> 
> You can use the class operator to determine if two objects are instances of the same exemplar:
> 
> if (class p === class q) ...
> 
> Note that this works for instances of both class and object exemplars.  However, if you want to test if an object is an instance of a specific named object exemplar then you need to remember that  such exemplars are prototype instances rather than constructor functions.  Of course, if you prefer object exemplars you are probably used to thinking in that prototypal style. You would express this as:
> 
> if (class p === class Point) ...  //for this example, assume the very first definition of Point
> 
> Finally, you might use class to create a new instance of the same exemplar as some other known object:
> 
> let mine = new class theirs;
> 
> This works the same regardless of whether the value of "theirs" is an object or class exemplar.
> 
> Relationship between the class and instanceof operators
> 
> There isn't one.  They are different operators.  class is simply a short hand for accessing an object's constructor property  instanceof tests a specific inheritance relationship. 
> 
> 
> 
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20111114/aa5bf29d/attachment.html>


More information about the es-discuss mailing list