Upload
brendan-eich
View
8.511
Download
4
Embed Size (px)
DESCRIPTION
My SPLASH Keynote on "the JavaScript World Domination Plan at 16 Years."
Citation preview
The JavaScript World Domination Plan at 16 Years
• History
• Controversies
• Performance
• ES.next
• Demos
Thursday, October 27, 2011
mozilla
History
2
Thursday, October 27, 2011
mozilla
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
• 2009: ES5: “use strict”, JSON, Object.create, etc.
3
Thursday, October 27, 2011
mozilla
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”
4
Thursday, October 27, 2011
mozilla
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
5
Thursday, October 27, 2011
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.write
Thursday, October 27, 2011
mozilla
7
Thursday, October 27, 2011
mozilla
8
Thursday, October 27, 2011
mozilla
(credit for last two slides)
• Kleber & Jain, "Don't Let Third Parties Slow You Down" (Velocity 2010)
• Upshot: incremental/progressive/asynchronous code loading required for speed with responsiveness (Java class loading counterexample)
9
Thursday, October 27, 2011
mozilla
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!
10
Thursday, October 27, 2011
mozilla
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...
11
Thursday, October 27, 2011
mozilla
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)
• Now behind a click-to-activate barrier/whitelist in Chrome
12
Thursday, October 27, 2011
mozilla
JS in two slides
• Objects map strings to values (properties):
var obj = new Object;obj[“prop”] = 42;!! ! // => obj.propobj[“0”] = “hello”;! ! // => obj[0]
other = {prop: 99, 0: “goodbye”}; // an object literalarray = [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”;result = array.map(fact);
13
Thursday, October 27, 2011
mozilla
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, grobgrob(6);!! ! ! // => undefined + 6 == NaNprop = “hello”;! // => reset global prop to stringgrob(6);!! ! ! // => prop == “hello6”
14
Thursday, October 27, 2011
mozilla
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
15
Thursday, October 27, 2011
mozilla
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 colorold = new Car(“Ford”, “T”);!! // black Model TmyCar.color = “silver”;!! ! // silver Honda Fit
• Powerful when combined with closures
16
Thursday, October 27, 2011
mozilla
Controversies
17
Thursday, October 27, 2011
mozilla
Why no bytecode?
• Top engine implementors won't 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
18
Thursday, October 27, 2011
mozilla
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
19
Thursday, October 27, 2011
mozilla
20
Thursday, October 27, 2011
mozilla
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
21
Thursday, October 27, 2011
mozilla
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?
22
Thursday, October 27, 2011
mozilla
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
• == and != are not equivalance relations (so use === and !==)
23
Thursday, October 27, 2011
mozilla
Performance
24
Thursday, October 27, 2011
mozilla
Performance progress - V8
25
Thursday, October 27, 2011
mozilla
Tuning for SunSpider [Richards, Vitek, et al.]
26
Thursday, October 27, 2011
mozilla
Recent progress - SpiderMonkey Type Inference
27
Thursday, October 27, 2011
mozilla
ES.next
28
Thursday, October 27, 2011
mozilla
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
29
Thursday, October 27, 2011
mozilla
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);
30
Thursday, October 27, 2011
mozilla
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)
31
Thursday, October 27, 2011
mozilla
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 } }]);
32
Thursday, October 27, 2011
mozilla
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`
• Multiline regexp literals: re`literalPart1${substitution} (yes, that was a newline!) \w+ literalPart2`
33
Thursday, October 27, 2011
mozilla
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]; }}
34
Thursday, October 27, 2011
mozilla
(tentative syntax ahead, work in progress...)
35
Thursday, October 27, 2011
mozilla
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
36
Thursday, October 27, 2011
mozilla
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}
37
Thursday, October 27, 2011
mozilla
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}
38
Thursday, October 27, 2011
mozilla
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”
39
Thursday, October 27, 2011
mozilla
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
print(b); // [1, 4, 9, 16]
40
Thursday, October 27, 2011
mozilla
More block lambda revival
• Paren-free calls, control effects: you know you want it...
41
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
Thursday, October 27, 2011
mozilla
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
42
Thursday, October 27, 2011
mozilla
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 O'Browser 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
• Others: Oia Quixe Gnusto Logo p2js Reb2Static RPN phype OP4JS jsForth wForth
43
Thursday, October 27, 2011
mozilla
Demos
44
Thursday, October 27, 2011
mozilla
Emscripten [Alon Zakai]
45
Thursday, October 27, 2011
mozilla
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!
46
Thursday, October 27, 2011
mozilla
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);
47
Thursday, October 27, 2011
mozilla
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 ); . . .
48
Thursday, October 27, 2011
mozilla
River Trail [Intel Labs]
49
Thursday, October 27, 2011
mozilla
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
50
Thursday, October 27, 2011
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 JS
Thursday, October 27, 2011
mozilla
Q&A
• @BrendanEich on twitter
• http://www.brendaneich.com/
52
Thursday, October 27, 2011