Your SlideShare is downloading. ×
0
Extensible Operators and Literals for JavaScript
Extensible Operators and Literals for JavaScript
Extensible Operators and Literals for JavaScript
Extensible Operators and Literals for JavaScript
Extensible Operators and Literals for JavaScript
Extensible Operators and Literals for JavaScript
Extensible Operators and Literals for JavaScript
Extensible Operators and Literals for JavaScript
Extensible Operators and Literals for JavaScript
Extensible Operators and Literals for JavaScript
Extensible Operators and Literals for JavaScript
Extensible Operators and Literals for JavaScript
Extensible Operators and Literals for JavaScript
Extensible Operators and Literals for JavaScript
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Extensible Operators and Literals for JavaScript

676

Published on

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

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

Published in: Software
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
676
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
0
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Operators and Literals Brendan Eich brendan.eich@gmail.com @BrendanEich Ecma TC39 May 2015
  • 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. 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. 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. Overloadable Operators •| ^ & •== •< <= •<< >> >>> •+ - •* / % •unary- unary+ boolean-test!! ~ • ISSUES: lost invariants in spite of overloadable subset
  • 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. 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. 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. 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. 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. 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. 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. 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. 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)

×