FFFF samples/javascript2.md at master · slideshow-s9/samples · GitHub
[go: up one dir, main page]

Skip to content

Latest commit

 

History

History
406 lines (304 loc) · 13.4 KB

File metadata and controls

406 lines (304 loc) · 13.4 KB

title: JavaScript 2 and the Open Web

JavaScript 2 and the Open Web

Brendan Eich (Mozilla) @media Ajax London, November 2007

(Adapted S9 Version from Original S5 Slide Deck)

Cui Bono - Who decides what is "better"?

  • Browser, plugin, and OS vendors?
  • Web developers?
  • All of the above, ideally
    • Without taking too long
    • Or making a mess
  • Preventing change could spare us from "worse"
  • Or help proprietary "change" to take off for the worst

Inevitable Evolution

  • Web browsers are evolving
  • They need to, against Microsoft Silverlight, Adobe Intergrated Runtime (AIR), and OS stacks
  • Browsers (and plugins!) need all three of
    1. Better Security
    2. Better APIs for everything (see 1)
    3. Better programming language support (see 1 and 2)
  • No two-legged stools, all three are needed

Evolving Toward "Better"

  • Security: hard problem, humans too much in the loop
  • APIs: served by Web Hypertext Application Technology Working Group (WHAT-WG) (Apple, Mozilla, Opera)
  • Languages: only realistic hope in the short run is JavaScript 2

Alternative Languages

  • Why not new/other programming languages?
  • JavaScript not going away in our lifetimes
  • JavaScript code is growing, not being rewritten
  • No room for multiple language runtimes in mobile browser
    • Apple, Mozilla, Opera attest to this in my hearing
  • One multi-language runtime? Eventually, not soon enough
    • A patent minefield...
    • How many hard problems can we (everyone!) solve at once and quickly?

Why JavaScript 2

  • JavaScript 1 is too small => complexity tax on library and app authors
  • JavaScript 1 has too few primitives => hard idiom optimization problem
  • JavaScript 1 lacks integrity features => better security has to be bolted on
  • JavaScript 1 is not taught much => Java U. still cranking out programmers
  • JavaScript 2 aims to cover the whole user curve, "out of the box"

Normal Distribution

Wait a Minute!

Perhaps you object (strenously):

  • I like my JavaScript small, it is not complex with the right kung-fu!
  • Most runtime is in the DOM, who cares about JavaScript optimizations
  • Security through smallness, and anyway: fix security first
  • People are learning, Yoda is teaching them

OK, Granted

  • Some truth in these claims, just not enough in my view
  • The odds ratios multiply to a pretty small success likelihood
  • Meanwhile, Microsoft Silverlight is charging hard with C# (DLR fan-bait aside)
  • Adobe Flash and Adobe Integrated Runtime (AIR) likewise rely on ActionScript 3, not JavaScript 1, to compete
  • And really, JavaScript 1 users who are hitting its limits need relief soon

Why Not Evolve?

  • We're not proto-humans from 2001: A Space Odyssey
    • Making space ships out of bones
    • Or modules out of lambdas
  • We're highly-evolved tool users, with opposable thumbs -- we can:
  • Make better use of an existing tool (JavaScript 1)
  • Improve the tool itself (JavaScript 2)
  • Why not do both?

But... But...

You may still object:

  • JavaScript should remain small no matter what!
  • Classes suck, I hate my pointy-haired Java boss
  • Aren't you rejecting your own elegant (yet messy) creation?
  • Who replaced you with a pod-person? We don't even know you any longer!

What I Seek

  • To make JavaScript (not people)... better
  • Better for its present and near-future uses on the web
  • Especially for building Ajax libraries and applications
  • JavaScript programs are increasing in size and complexity
  • They face increasing workload -- lots of objects, runtime
  • JavaScript users deserve improvements since JavaScript 1/EmcaScript 3 (eight years ago)

In Particular

  • JavaScript users deserve an optional type system
    • Instead of tedious (often skipped) error checking
    • So APIs can prove facts about their arguments
    • Without requiring all calling code to be typed
    • (... at first, or ever!)
  • They deserve integrity guarantees such as const
  • They deserve real namespaces, packages, compilation units
  • They deserve some overdue "bug fixes" to the EmcaScript 3 (ES3) standard
  • They deserve generous syntactic sugar on top

The Deeper Answer

Why JavaScript 2 as a major evolutionary jump matters:

  • So browsers and plugins lose their "native-code innovation" lock
  • Downloaded JavaScript 2 code can patch around old native code bugs
  • Or reimplement a whole buggy subsystem, at near-native (or better!) speed
  • No more waiting for Internet Explorer(or Firefox, or Safari, or Opera)
  • Distributed extensibility, web developers win

Believe It

  • Yes, this was the Java dream that died in 1995, or 1997
  • This time for sure (Tamarin may be the most widely deployed VM ever)
  • It's coming true with JavaScript -- if only it can evolve enough in time

Non-Issues

  • JavaScript 1 performance on synthetic pure-JavaScript (no DOM) benchmarks
  • Trace-based JITing accelerates JavaScript 1 at least an order of magnitude
  • Work from Michael Franz's group at UC Irvine (Mozilla supported)
  • No int type annotations required
  • Preliminary results (from submitted papers) based on Tamarin-to-Java bytecode translation, with a custom tracing JIT targeting the JVM (whew!), next...

Tracing JIT Benchmarks

Tracing JIT Benchmarks

Non-Issues (2)

  • Making JavaScript 2 look like any other language
  • Stuart, yesterday : fans already fake JavaScript 1 to resemble Ruby, Python, ...
  • But: JavaScript 2 learns from other languages
    • ActionScript 3: nominal types, namespaces, packages
    • Python: iterators and generators, catch-alls
    • Dylan, Cecil: generic methods
  • Only those who don't learn history are doomed to repeat it
  • Problems will be shaken out in JavaScript 2/EmcaScript 4 "beta"
    • No rubber-stamped standards! (cough OOXML)

Integrity in JavaScript 2

  • Object, Array, etc., globals can be replaced in JavaScript 1
    • JSON CSRF hazards pointed out by Joe Walker
    • ECMA spec says this matters, or not, half the time
    • JavaScript 2 makes the standard class bindings immutable
  • Objects are mutable, extensible
    • Even with privileged/private members via closures
    • Too easy to forge instance of special type
    • JavaScript 2 has class exactly to solve this problem
    • JavaScript 2 lets users make fixtures, fixed ("don't delete") properties
  • JavaScript 1 user-defined properties can be replaced/hijacked
    • JavaScript 2 has const and final

Evolutionary Programming

Version 1 of a webmail client, in almost pure JavaScript 1

function send(msg) {
    validateMessage(msg);
    msg.id = sendToServer(JSON.encode(msg));
    database[msg.id] = msg;
}

function fetch() {
    handleMessage(-1);   // -1 means "get new mail"
}

Evolutionary Programming (2)

function get(n) {
    if (uint(n) !== n)   // JS1: n>>>0 === n
        throw new TypeError;
    if (n in database)
        return database[n];
    return handleMessage(n);
}

var database = [];

Evolutionary Programming (3)

function handleMessage(n) {
    let msg = JSON.decode(fetchFromServer(n));
    if (typeof msg != "object")
        throw new TypeError;
    if (msg.result == "no data")
        return null;
    validateMessage(msg);
    return database[msg.id] = msg;
}

Evolutionary Programming (4)

function validateMessage(msg) {
    function isAddress(a)
        typeof a == "object" && a != null &&
        typeof a.at == "object" && msg != null &&
        typeof a.at[0] == "string" && typeof a.at[1] == "string" &&
        typeof a.name == "string";
    if (!(typeof msg == "object" && msg != null &&
        typeof msg.id == "number" && uint(msg.id) === msg.id &&
        typeof msg.to == "object" && msg != null &&
        msg.to instanceof Array && msg.to.every(isAddress) &&
        isAddress(msg.from) && typeof msg.subject == "string" &&
        typeof msg.body == "string"))
        throw new TypeError;
}

Evolution, Second Stage

Version 2: Structural types for validation.

type Addr = { at: [string, string], name: string };
type Msg = {
    to: [Addr], from: Addr, subject: string, body: string, id: uint
};

function send(msg: like Msg) {
    msg.id = sendToServer(JSON.encode(msg));
    database[msg.id] = msg;
}

function fetch()
    handleMessage(-1);

Evolution, Second Stage

function get(n: uint) {
    if (n in database)
        return database[n];
    return handleMessage(n);
}

function handleMessage(n) {
    let msg = JSON.decode(fetchFromServer(n));
    if (msg is like { result: string } && msg.result == "no data")
        return null;
    if (msg is like Msg)
        return database[msg.id] = msg;
    throw new TypeError;
}

Evolution, Third Stage

Version 3a: Integrity through structural type fixtures (other functions are unchanged since Version 2)

type MsgNoId = {
    to: [Addr], from: Addr, subject: string, body: string
};

function send(msg: like MsgNoId) {
    msg.id = sendToServer(JSON.encode(msg));
    database[msg.id] = copyMessage(msg);
}

Evolution, Third Stage (2)

function handleMessage(n) {
    let msg = JSON.decode(fetchFromServer(n));
    if (msg is like { result: string } && msg.result == "no data")
        return null;
    if (msg is like Msg)
        return database[id] = copyMessage(msg);
    throw new TypeError;
}

Evolution, Third Stage (3)

function copyMessage(msg) {
    function newAddr({ at: [user, host], name })
        new Addr([user, host]: [string, string], name);

    let { to, from, subject, body, id } = msg;
    return new Msg(to.map(newAddr), newAddr(from),
                                 subject, body, id);
}

Alternative Third Stage

Version 3b (other functions are unchanged since Version 3a)

function send(msg: like MsgNoId) {
    msg.id = sendToServer(JSON.encode(msg))
    database[msg.id] = msg wrap Msg
}

function handleMessage(n) {
    let msg = JSON.decode(fetchFromServer(n))
    if (msg is like { result: string } && msg.result == "no data")
        return null
    return database[msg.id] = msg wrap Msg
}

Observations on Evolution

  • At no point so far did clients have to use types
  • Code shrank by half from stage 1 to 3a, more to 3b
  • First stage just used a tiny bit of JavaScript 2 (uint)
  • Second stage added structural types and is like tests
    • Sanity-checking the "shape" of API arguments
    • But trusting the client not to mutate behind the library's back!
  • Third stage copied into structural type instances with fixtures -- integrity against confused/malicious client
  • Alternative third stage used wrap instead

Observations on Evolution (2)

  • A "modularization" stage would use package or namespace
  • If copying or wrapping too costly, drop like from formal params, and either:
    • Change client to pass structural type instances
    • Or use nominal types (class, interface) throughout
    • Either way, client changes required at this point
  • Use optional strict mode for verification before deployment
  • (Many thanks to Lars Thomas Hansen for the example code)

Conclusions

  • JavaScript 2 focused on programming in the large and code migration:
    • Evolutionary programming with structural types
    • Gradual typing from like to wrap or fixed types
  • Rapid prototypes start out untyped, just like today
  • We believe most web JavaScript can remain untyped, with good performance
  • Library APIs and implementations can buy integrity and efficiency by the yard
  • Higher integrity with efficiency may induce more "islands" of typed code (e.g., real-time games)

What Else Is New?

  • ScreamingMonkey lives! It runs a self-hosted JavaScript 2/EmcaScript 4 compiler that generates bytecode from the compiler's own source
  • Much optimization work remains to be done
  • But the C# chess demo from MIX07, ported to EmcaScript 4, runs now
  • ScreamingMonkey chess demo is ~15x faster than the JScript version (per fresh e-mail today from Mark Hammond)
  • Demos of two other new APIs, the <video> tag and 3D <canvas>, follow...

Video Tag Demo

  • Implements the WHAT-WG <video> tag proposal
  • Opera and now Apple have implemented too
  • page-defined DHTML playback controls
  • Uses Ogg Theora and Vorbis for video and audio
  • Embeds <video> in SVG <foreignObject> for transforms
  • Developed by Chris Double

Canvas3D Demo

  • Alternative OpenGL-ES rendering context for <canvas>
  • Now available as a Firefox 3 addon!
  • Embeds OpenGL's shader language in <script>, read via DOM
  • Example KMZ (Google Earth) viewer
  • Developed by Vladimir Vukicevic
0