Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.
Operators and Literals
Brendan Eich
brendan.eich@gmail.com
@BrendanEich
Ecma TC39 May 2015
Value Types Review
• Int64, Uint64 (note capitalized names)
• Int32x4, Int32x8, etc. (SIMD)
• Float32 (to/from Float32Arra...
Value Types Review, 2
var ColorType =
ValueType(Symbol(“Color"), // or Symbol.for?
{r: Uint8, g: Uint8, b: Uint8, a: Uint8...
Literal Syntax
• Int64(0) ==> 0L // as in C#
• Uint64(0) ==> 0UL // as in C#
• Float32(0) ==> 0f // as in C#
• Bignum(0) =...
Overloadable Operators
•| ^ &
•==
•< <=
•<< >> >>>
•+ -
•* / %
•unary- unary+ boolean-test!! ~
• ISSUES: lost invariants i...
Preserving Boolean Algebra
• != and ! are not overloadable, to preserve
identities including
• X ? A : B <=> !X ? B : A
• ...
Preserving Relational Relations
• > and >= are derived from < and <= as follows:
• A > B <=> B < A
• A >= B <=> B <= A
• W...
Strict Equality Operators
• The strict equality operators, === and !==,
cannot be overloaded
• They work on frozen-by-defin...
Why Not Double Dispatch?
• Left-first asymmetry (v value, n number):
• v + n ==> v.add(n)
• n + v ==> v.radd(n)
• Anti-modu...
Cacheable Multimethods
• Proposed in 2009 by Christian Plesner Hansen
(Google) in es-discuss
• Avoids double-dispatch draw...
Binary Operator Example
• For v + u with either a value type instance:
• Let p = v.[[Get]](@@ADD)
• If p is not an Operato...
Reflect API Example
function addPointAndNumber(a, b) {
return Point(a.x + b, a.y + b);
}
Reflect.defineOperator('+', addPoi...
Subclassing Problem
• Given class A and class B extends A,
• Reflect.defineOperator(‘+’, addAA, A, A);
• Reflect.defineOpe...
Subclassing Solution
• OperatorSet stores (depth, method) pairs
• Reflect.defineOperator(‘+', addBB, B, B);
copies B’s ini...
Prochain SlideShare
Chargement dans…5
×

Extensible Operators and Literals for JavaScript

Updated from Value Objects talks to separate Operators and Literals from Value Types as championed by Niko Matsakis and now Daniel Ehrenberg.

  • Identifiez-vous pour voir les commentaires

Extensible Operators and Literals for JavaScript

  1. 1. Operators and Literals Brendan Eich brendan.eich@gmail.com @BrendanEich Ecma TC39 May 2015
  2. 2. Value Types Review • Int64, Uint64 (note capitalized names) • Int32x4, Int32x8, etc. (SIMD) • Float32 (to/from Float32Array today) • Float32x4, Float32x8 (SIMD) • Bignum • Decimal (long-time TC39 goal for IBM: self-hosted) • Complex • Rational
  3. 3. Value Types Review, 2 var ColorType = ValueType(Symbol(“Color"), // or Symbol.for? {r: Uint8, g: Uint8, b: Uint8, a: Uint8}); ColorType.prototype.average = function() { return (this.r + this.g + this.b) / 3; }; var color = ColorType({r: 22, g: 44, b: 66, a: 88}); color.average() // yields 44 assert(typeof color == “color”); // un-capitalized! // ISSUE: some web JS hardcodes known typeof results
  4. 4. Literal Syntax • Int64(0) ==> 0L // as in C# • Uint64(0) ==> 0UL // as in C# • Float32(0) ==> 0f // as in C# • Bignum(0) ==> 0n // avoid i/I • Decimal(0) ==> 0m // or M, C/F# • Lexically transpose, e.g., 0L into L(0) • Sanity: map short suffix to constructor name • Reflect.defineSuffix(‘L’, Int64) • or literalSuffixTable.L(‘0’) h/t @littledan • or use imported names only? h/t @sebmarkbåge
  5. 5. Overloadable Operators •| ^ & •== •< <= •<< >> >>> •+ - •* / % •unary- unary+ boolean-test!! ~ • ISSUES: lost invariants in spite of overloadable subset
  6. 6. Preserving Boolean Algebra • != and ! are not overloadable, to preserve identities including • X ? A : B <=> !X ? B : A • !(X && Y) <=> !X || !Y • !(X || Y) <=> !X && !Y • X != Y <=> !(X == Y) • ISSUE: implicit-!!(x) vs. !(!x)
  7. 7. Preserving Relational Relations • > and >= are derived from < and <= as follows: • A > B <=> B < A • A >= B <=> B <= A • We provide <= in addition to < rather than derive A <= B from !(B < A) in order to allow the <= overloading to match the same value object’s == semantics • And for unordered values (NaNs)
  8. 8. Strict Equality Operators • The strict equality operators, === and !==, cannot be overloaded • They work on frozen-by-definition value objects via a structural recursive strict equality test (beware, NaN !== NaN) • Same-object-reference remains a fast-path optimization
  9. 9. Why Not Double Dispatch? • Left-first asymmetry (v value, n number): • v + n ==> v.add(n) • n + v ==> v.radd(n) • Anti-modular: exhaustive other-operand type enumeration required in operator method bodies • Consequent loss of compositionality: Complex and Rational cannot be composed to make Ratplex without modifying source or wrapping in proxies
  10. 10. Cacheable Multimethods • Proposed in 2009 by Christian Plesner Hansen (Google) in es-discuss • Avoids double-dispatch drawbacks from last slide: binary operators implemented by 2-ary functions for each pair of types • Supports Polymorphic Inline Cache (PIC) optimizations (Christian was on theV8 team) • Background reading: [Chambers 1992]
  11. 11. Binary Operator Example • For v + u with either a value type instance: • Let p = v.[[Get]](@@ADD) • If p is not an OperatorSet, throw a TypeError • Let q = u.[[Get]](@@ADD_R) • If q is not an OperatorSet, throw a TypeError • Let r = p.join(q) (r an Array) • If r.length != 1 throw a TypeError • Let f = r[0]; if f is not a function, throw • Evaluate f(v, u) and return the result
  12. 12. Reflect API Example function addPointAndNumber(a, b) { return Point(a.x + b, a.y + b); } Reflect.defineOperator('+', addPointAndNumber, Point, Number); function addNumberAndPoint(a, b) { return Point(a + b.x, a + b.y); } Reflect.defineOperator('+', addNumberAndPoint, Number, Point); function addPoints(a, b) { return Point(a.x + b.x, a.y + b.y); } Reflect.defineOperator('+', addPoints, Point, Point); // NB: Calling defineOperator with 3 args defines unary operator
  13. 13. Subclassing Problem • Given class A and class B extends A, • Reflect.defineOperator(‘+’, addAA, A, A); • Reflect.defineOperator(‘+', addBB, B, B); • a1 + a2 must select addAA • a1 + b2 and b1 + a2 must select addAA • b1 + b2 must select addBB not addAA • How should OperatorSet implement this?
  14. 14. Subclassing Solution • OperatorSet stores (depth, method) pairs • Reflect.defineOperator(‘+', addBB, B, B); copies B’s initial @@ADD and @@ADD_R operator- sets from A’s @@ADD and @@ADD_R sets • OperatorSet.join, on finding intersection not a singleton, breaks tie by maximum prototype depth: (2, addBB) > (1, addAA)

×