• Like
Splash
Upcoming SlideShare
Loading in...5
×

Splash

  • 8,106 views
Uploaded on

My SPLASH Keynote on "the JavaScript World Domination Plan at 16 Years."

My SPLASH Keynote on "the JavaScript World Domination Plan at 16 Years."

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
8,106
On Slideshare
0
From Embeds
0
Number of Embeds
3

Actions

Shares
Downloads
56
Comments
0
Likes
11

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. JavaScript World The Domination Plan at 16 Years brendan@mozilla.org • History • Controversies • Performance • ES.next • DemosThursday, October 27, 2011
  • 2. History mozilla 2Thursday, October 27, 2011
  • 3. A very brief history • Ten days in May 1995: “Mocha”, form validation, img rollovers, scripting of Java • September 1995: “LiveScript” (did Netscape marketing go to Microsoft after?) • December 1995: “JavaScript”, thanks to Bill Joy (a Sun Founder) • 1996-1997: ECMA-262 Ed. 1, aka ES1, thanks to ECMA (now Ecma) TC39 • 1999: ES3: function expressions, RegExp, try/catch/finally, switch, do-while • 2005: the Ajax revolution, followed by “The Ajax Experience” • 2008: ES4 RIP, Harmony founded in July at the Oslo TC39 meeting mozilla • 2009: ES5: “use strict”, JSON, Object.create, etc. 3Thursday, October 27, 2011
  • 4. Netscape in 1995 • Netscape had 50-80% browser share during explosive early Web growth • Microsoft low-ball buy-out attempt in late 1994 rebuffed • Threat to Windows made explicit by Java and too much hype • “Worse is Better!” - @pmarca channeling @rpg • “We are doomed!” - engineering refrain • Very narrow window in which to innovate and “get on first” mozilla 4Thursday, October 27, 2011
  • 5. Pitch to me: come do “Scheme in the browser” • One-shot opportunity to create the “HTML scripting language” • By the time I joined, the Netscape/Sun “Java deal” cast long shadow • Engineering VP: “make it look like Java” (I made it look like C and AWK) • Argument by code demonstration became necessary • I hacked the “Mocha” prototype in 10 days in May 1995 • And it showed. Mistakes (some recapitulating LISP) were frozen early • I spent the rest of 1995 embedding in the browser, creating the DOM mozilla 5Thursday, October 27, 2011
  • 6. Primordial DOM • Netscape lacked a persistent DOM tree model; it had only a flattened display list • To avoid slowing page load performance, I built the primordial DOM lazily from the display list • Hence, document.writeThursday, October 27, 2011
  • 7. mozilla 7Thursday, October 27, 2011
  • 8. mozilla 8Thursday, October 27, 2011
  • 9. (credit for last two slides) • Kleber & Jain, "Dont Let Third Parties Slow You Down" (Velocity 2010) • Upshot: incremental/progressive/asynchronous code loading required for speed with responsiveness (Java class loading counterexample) mozilla 9Thursday, October 27, 2011
  • 10. Initial design goals • Make it easy for non-experts to copy/paste snippets of code into HTML • Tolerate “minor” errors (e.g., missing semicolons) • Simplified onclick, onmousedown, etc., event handling, inspired by HyperCard • Pick a few hard-working, powerful primitives • First class functions for procedural abstraction (AWK more than Scheme) • Objects everywhere, prototype-based (Self, but only one parent per object) • Leave all else out! mozilla 10Thursday, October 27, 2011
  • 11. Marketing, sigh • Netscape management fretted: “Why two programming languages?” • Answer: division of labor, specialization • Java for high-priced components/widgets (applet/plugin model) • “Mocha” for mass market web designers (glue between components) • Primitive types vs. objects patterned after Java with LiveConnect in mind • “Object-based”, not object-oriented (no class) -- cannot have JS/Robin-the- boy-hostage encroaching on Java/Batman... mozilla 11Thursday, October 27, 2011
  • 12. Name games, the J word • Then Netscape changed the name to “LiveScript” • Finally, with Bill’s help on behalf of Sun, to “JavaScript” in December 1995 • Mostly a marketing scam • Engineering pressure to “be like Java” did cause us to follow Java into some dead ends (Date inherited y2k bugs from java.util.Date) • In the last decade Java has almost disappeared on the client side of the Web • Java is top moneymaker as malware kit vector (per Brian Krebs) mozilla • Now behind a click-to-activate barrier/whitelist in Chrome 12Thursday, October 27, 2011
  • 13. JS in two slides • Objects map strings to values (properties): var obj = new Object; obj[“prop”] = 42;!! ! // => obj.prop obj[“0”] = “hello”;! ! // => obj[0] other = {prop: 99, 0: “goodbye”}; // an object literal array = [0, 1, 2, 3, 4, 5, 6, 7]; // array.length == 8 • Functions are first-class objects: function fact(n) { return (n <= 2) ? n : n * fact(n-1); } fact.desc = “Factorial function”; mozilla result = array.map(fact); 13Thursday, October 27, 2011
  • 14. JS in two slides (2) • Methods are function-valued properties: obj.frob = function (n) { this.prop += n; }; obj.frob(6);! ! // => obj.prop == 48 • Top-level scope is an object. Implicit conversion. Oops. grob = obj.frob;! // => assign a global method, grob grob(6);! ! ! ! // => undefined + 6 == NaN prop = “hello”;! // => reset global prop to string grob(6);! ! ! ! // => prop == “hello6” mozilla 14Thursday, October 27, 2011
  • 15. Closures • function Y(g) { return function (f) {return f(f);}( function (f) {return g(function (x) { return f(f)(x); }); }); } • var fact = Y(function (fact) { return function (n) { return (n <= 2) ? n : n * fact(n-1); } }); alert(fact(5));! => 120 mozilla 15Thursday, October 27, 2011
  • 16. Prototypes • All user-defined functions can construct: function Car(make, model) { this.make = make; this.model = model; } myCar = new Car(“Honda”, “Fit”); • All user-defined functions have a prototype property: Car.prototype.color = “black”;!// default color old = new Car(“Ford”, “T”);! ! // black Model T myCar.color = “silver”;! ! ! // silver Honda Fit mozilla • Powerful when combined with closures 16Thursday, October 27, 2011
  • 17. Controversies mozilla 17Thursday, October 27, 2011
  • 18. Why no bytecode? • Top engine implementors wont agree on one bytecode • Lowering JS semantics too far from source is future-hostile • Versioning is anathema on the web (JVM, Flash counterexamples) • JS with a few evolutionary steps is already a decent “bytecode” • TypedArrays, binary data: machine storage types • Type inference, runtime type/value profiling, proposed runtime guards • Compressed AST encoding a la JSZap [Livshits, Zorn] is likelier mozilla 18Thursday, October 27, 2011
  • 19. Why no multi-VM browser integration • Advantage: use canonical implementations, e.g., CPython for Python • Drawbacks: those canonical implementations are not ready for the web • Versioning independent of browser releases => dynamic linking/update • OS-specific low-level APIs, toolchain-specific FFIs • Insufficient fuzz-testing and web security engineering • Proxies among disjoint heaps require non-distributed garbage-cycle collection • Proxies among different languages a tall order otherwise mozilla 19Thursday, October 27, 2011
  • 20. mozilla 20Thursday, October 27, 2011
  • 21. No browser wins by taking overlarge risks • Previous slide from Collin Jackson’s USENIX Security 2011 invited talk, titled “Crossing the Chasm: Pitching Security Research to Mainstream Browser Vendors” [slides] • Features are not free • Mozilla commissioned optional CPython integration work by Mark Hammond • Used by only one embedder • No CPython distribution for Windows or Mac OS X • High sunk and recurring engineering costs mozilla 21Thursday, October 27, 2011
  • 22. Why no single multi-language VM? • IPR, NIH bad reasons, but... • Such VMs always build in advantages for one “lead language” (e.g., Java) • Rest of pack are incomplete copies of canonical implementations (Jython) • Large companies can perhaps afford to strive for completeness over time, other browser vendors cannot • See previous slide • JS as compiler target dramatically on the rise -- are we already here? mozilla 22Thursday, October 27, 2011
  • 23. JS has awful warts! • So use JSLint, JSHint, ADsafe, or better • Two example from primordial JS: • function f(o,x) { with (o) return x; } -- o.x or parameter x? • function g(s) { eval(s); return function(){ return x; } } cannot be analyzed to decide that s != “var x = ‘ha ha’” • Fixed in ES5 strict mode, which removes with and gives eval its own scope • ES.next (likely ES6) removes global object from scope chain: pure lexical scope mozilla • == and != are not equivalance relations (so use === and !==) 23Thursday, October 27, 2011
  • 24. Performance mozilla 24Thursday, October 27, 2011
  • 25. Performance progress - V8 mozilla 25Thursday, October 27, 2011
  • 26. Tuning for SunSpider [Richards, Vitek, et al.] mozilla 26Thursday, October 27, 2011
  • 27. Recent progress - SpiderMonkey Type Inference mozilla 27Thursday, October 27, 2011
  • 28. ES.next mozilla 28Thursday, October 27, 2011
  • 29. The Harmony goals • Be a better language for writing: • complex applications • libraries (including the DOM) shared by those applications • code generators targeting the new edition • Better tests, if not a testable (executable) specification • Adopt de facto standards where possible • Keep versioning as simple and linear as possible • Support a statically verifiable, object-capability subset mozilla 29Thursday, October 27, 2011
  • 30. Approved for ES.next • let, const, function in block scope f(“outer”); function f(x) { { let x = “inner”; print(x); } // prints “inner” print(x); // prints “outer” } • destructuring: let {x, y} = pt; let [s, v, o] = triple() • parameter default values: function f(x, y=1, {z=2, w=3}) {...} • rest, spread: function g(i, j, ...r) { return r.slice(i, j); } let a = [0, 1, 2, 3], b = [...a, 4, 5, 6, 7], o = new anyConstructor(...a), z = variadic(...a, -1, ...b); mozilla 30Thursday, October 27, 2011
  • 31. More approved for ES.next • proxies, weak maps: Proxy.create(handler, proto), new WeakMap • modules: module NewMath { export function sin(x) {...} } module Prefetch = “http://your/url/here”; • iterators, generators: function* gen() { yield 1; yield 2; } for (let i of gen()) print(i); // prints 1 and 2 • array comprehensions: return [x+y for x of a for y of b] • generator expressions: let g = (x+y for x of a for y of b) mozilla 31Thursday, October 27, 2011
  • 32. Yet more approved for ES.next • Binary data: • const Point2D = new StructType({ x: uint32, y: uint32 }), Color = new StructType({ r: uint8, g: uint8, b: uint8 }), Pixel = new StructType({ point: Point2D, color: Color }); • const Triangle = new ArrayType(Pixel, 3); • new Triangle([{ point: { x: 0, y: 0 }, color: { r: 255, g: 255, b: 255 } }, { point: { x: 5, y: 5 }, color: { r: 128, g: 0, b: 0 } }, { point: { x: 10, y: 0 }, color: { r: 0, g: 0, b: 128 } }]); mozilla 32Thursday, October 27, 2011
  • 33. String interpolation and templating • Injection-safer string interpolation and domain-specific languages • Backtick-quoted string desugars to a function call that operates on the literal portions and substitution results: • quasi`literalPart1${substitution}literalPart2` desugars to • quasi({raw: ["literalPart1", "literalPart1"], cooked: ["literalPart1", "literalPart1"]}, substitution) • Multiline string literals w/o prefix: `literalPart1${substitution} (yes, that was a newline!) literalPart2` mozilla • Multiline regexp literals: re`literalPart1${substitution} (yes, that was a newline!) w+ literalPart2` 33Thursday, October 27, 2011
  • 34. Classes squeaked by, but face existential doubt • Sugar for prototypal object pattern, also supports closure patterns: • const px = Name.create(‘x’), py = Name.create(‘y’); class Point extends Base { constructor(x, y) { super(); this[px] = x, this[py] = y; this.r = function() { return Math.sqrt(x*x + y*y); } } get x() { return this[px]; } get y() { return this[py]; } proto_r() { return Math.sqrt(this[px] * this[px] + this[py] * this[py]); } equals(p) { return this[px] === p[px] && this[py] === p[py]; } mozilla } 34Thursday, October 27, 2011
  • 35. (tentative syntax ahead, work in progress...) mozilla 35Thursday, October 27, 2011
  • 36. Triangle (the proto operator) • Instead of var obj = {__proto__: base, a: 1, b: 2}, use let obj = base <| {a: 1, b: 2} • Works for other literal object forms: let arr = base <| [p, q, r] let fun = base <| function (...args) { ... } let re = base <| /(w+)s+(w)+/g mozilla 36Thursday, October 27, 2011
  • 37. The monocle-mustache operator • Inspired by PrototypeJS’s Object.extend base.{a:1, b:2} // warning: updates base • Copies all “own” right-hand-side properties (including private names) to base • Should it generate a fresh value instead of mutating? let obj = base.{a:1, b:2} • Or if we want Prototype-style update, should it look like an assignment op? base .= {a:1, b:2} mozilla 37Thursday, October 27, 2011
  • 38. Class pattern using triangle-monocle-mustache • const px = Name.create(‘x’), py = Name.create(‘y’); let Point = Base <| function (x, y) { super(); this[px] = x, this[py] = y; this.r = function() { return Math.sqrt(x*x + y*y); } }.prototype.{ get x() { return this[px]; }, get y() { return this[py]; }, proto_r() { return Math.sqrt(this[px] * this[px] + this[py] * this[py]); }, equals(p) { return this[px] === p[px] && this[py] === p[py]; } }.constructor.{ allPoints: [] // class “static” property } mozilla 38Thursday, October 27, 2011
  • 39. Not yet in Harmony: arrow function syntax • Arrow function syntax, instead of λ, ƒ, or # (want to save # for later) • Just like CoffeeScript: let identity = (x) -> x • Expression body: const square = (x) -> (x * x) • Statement body: let countUsed = (str) -> { if (str in usedWords) usedWords[str]++; else usedWords[str] = 1; } • Fat arrow too: callback = (msg) => ( this.vmail.push(msg) ) • Binding forms: let f() -> “writable” const K() -> “readonly” mozilla 39Thursday, October 27, 2011
  • 40. Not yet in Harmony: block lambda revival • Inspired by Smalltalk via Ruby let empty = {||}; // no need for space between bars assert(empty() === undefined); assert(typeof empty === "function"); // native and implements [[Call]] assert(empty.length === 0);   let identity = {|x| x}; // completion is return value   assert(identity(42) === 42); assert(identity.length === 1);   let a = [1, 2, 3, 4]; let b = a.map {|e| e * e} // paren-free call with block is // idiomatic control structure so // no semicolon at end mozilla print(b); // [1, 4, 9, 16] 40Thursday, October 27, 2011
  • 41. More block lambda revival • Paren-free calls, control effects: you know you want it... b = a.map {|e| // newline in block ok e * e * e} // newline after ends call   function find_first_odd(a) { a.forEach { |e, i| if (e & 1) return i; } // returns from function return -1; }   function escape_return() { return {|e| return e}; } b = escape_return(); try { b(42); } catch (e) {} // error, return from // inactive function mozilla 41Thursday, October 27, 2011
  • 42. Good news • ES.next is being drafted • It has many usability and be-a-better-compiler-target improvements already • Prototyping in SpiderMonkey and V8 is ongoing, so we’ll actually implementor- and user-test before finalizing the specification • Even if we cut a few things -- still good progress • Help wanted on the implementor- and user-testing fronts mozilla 42Thursday, October 27, 2011
  • 43. Languages targeting JS today • CoffeeScript Family (& Friends): CoffeeScript Coco Parsec Contracts.coffee Uberscript ToffeeScript JS11 Kaffeine Jack move • JavaScript Parsers and Extensions: Narcissus Traceur es-lab qfox reflect.js bdParse parse-js ZeParser • Javascript Optimizers: Closure UglifyJS • Security enforcing JavaScript: Caja ADsafe FBJS Jacaranda etc. • Static or optional typing: Dart JavaScript++ SafeJS MileScript Mascara Roy • Synchronous to Asynchronous JavaScript Compilers (CPS): Streamline.js mobl StratifiedJS NarrativeJS jwacs Jscex TameJS • JavaScript Language Extensions: ContextJS Objective-J JS2 jangaroo Flapjax jLang RestrictMode TIScript • Ruby: HotRuby rb2js RubyJS Red Quby Opal 8ball • Python: PYXC-PJ Pyjamas Pyjs Skulpt PyCow PyvaScript • Java: GWT Java2Script j2js • Scala: scalagwt • C#, .NET: jsc JSIL Script# Prefix • Lisp, Scheme: BiwaScheme ClojureScript clojurejs EdgeLisp Fargo MobyScheme nconc Parenscript Ralph scheme2js Scriptjure Sibilant Spock • OCaml: Ocamljs OBrowser Js_of_ocaml • Haskell: ghcjs jmacro • Smalltalk: Amber Clamato SilverSmalltalk LivelyKernel • C/C++: Emscripten mala Clue • Basic: NS Basic/App Studio, qb.js • Multitarget: Haxe Fantom LZX Clue • • Tierless languages (produce both client & server): Fun Ur WebSharper mobl E Sugar Opa Visual, Blocks-based Languages: Waterbear JsMorphic ScriptBlocks mozilla • Others: Oia Quixe Gnusto Logo p2js Reb2Static RPN phype OP4JS jsForth wForth 43Thursday, October 27, 2011
  • 44. Demos mozilla 44Thursday, October 27, 2011
  • 45. Emscripten [Alon Zakai] mozilla 45Thursday, October 27, 2011
  • 46. RiverTrail: Parallel JS • A ParallelArray library, like typed arrays but immutable. • map, reduce, combine, filter, partition, scan, scatter -- all produce fresh ParallelArray results • Relies on associativity to parallelize arithmetic operations (this does inject some f.p. non-determinism). • A Firefox add-on that runs a Narcissus-based JS-to-OpenCL compiler over ParallelArray code • Source: github.com/RiverTrail/RiverTrail (user id should’ve been IntelLabs) • Demo code contains a "DO NOT use strict”; directive! mozilla 46Thursday, October 27, 2011
  • 47. RiverTrail demo sample code • the ParallelArray constructor builds on typed arrays: NBody.private.initVel = new Array(numBodies); NBody.private.initVelTA = new Float32Array(numBodies * 4); var initAsteroidPos = new Array(50); for (i = 0; i < 50; i++) {     initAsteroidPos[i] = new ParallelArray([                                             NBody.private.posTA[i * 3 + 0],     // x                                             NBody.private.posTA[i * 3 + 1],                                             NBody.private.posTA[i * 3 + 2],                                             ]); }   . . . NBody.private.asteroidPos = new ParallelArray(Float32Array, initAsteroidPos);   . . . NBody.private.vel = new ParallelArray(Float32Array, NBody.private.initVel); mozilla 47Thursday, October 27, 2011
  • 48. ParallelArray methods in action • combine method is a workhorse (takes variable number of args) "animateTickParallel": function animateTickParallel() {     // increment (+=) velocity by acceleration     var newVel = NBody.private.vel.combine(                  1,                      low_precision(NBody.bodyVelocityLoopified),                      NBody.private.pos,                      numBodies,                      NBody.Constant.deltaTime,                      NBody.Constant.epsSqr,                      NBody.time,                      NBody.private.asteroidPos                  );   . . . mozilla 48Thursday, October 27, 2011
  • 49. River Trail [Intel Labs] mozilla 49Thursday, October 27, 2011
  • 50. Conclusions • JS is everywhere, it’s evolving, and it will die hard • JS is not the bad guy • No world domination by (under-funded) force -- not Dr. Evil • Developers have learned how to use it well • More like the good guy in the wrong place at the wrong time • Bruce Willis in the Die Hard series... • or current inspiration: classic Wesley Snipes mozilla 50Thursday, October 27, 2011
  • 51. Always bet on JS • First they said JS couldn’t be useful for building “rich Internet apps” • Then they said it couldn’t be fast • Then they said it couldn’t be fixed • Then it couldn’t do multicore/GPU • Wrong every time! • My advice: always bet on JSThursday, October 27, 2011
  • 52. Q&A • @BrendanEich on twitter • brendan@mozilla.org • http://www.brendaneich.com/ • es-discuss@mozilla.org mozilla 52Thursday, October 27, 2011