JavaScript at 20

Brendan Eich

Standardization

"Things that are impossible just take longer." - Hixie

1995: Eich recruited to Netscape

"Come and put Scheme in the browser!"

2015: John Carmack put Racket in Oculus VR


What was it like to hack JS in 10 days?

Painful.


Java was the big Web VM

JavaScript was "little brother"

Think back to 1995... what was on TV then?

I had my big break that year...

Even @pmarca roller-bladed then.

I'd go to a real library to read Computer Science papers.

John Doerr claims that even an idiot could have been a successful VC in the 1980s:

"All you had to do was hang around Margaret Jacks Hall."

Java's bytecode design influenced my work on JS.

Java is typed (or statically typed) and has mostly-typed bytecode

JS is untyped (or dynamically typed)

So in 10 days in May 1995, I wrote

Mistakes were made (WTFJS, WAT)

But enough was good that JS survived

http://whitetailbutte.com/ case study

Early DOM mattered as much as JS

Much progress since then

class vector {
  constructor(n) { this.arr = new Int32Array(n); }
  sum() {
    let la = this.arr;
    let S = 0;
    for (let i = la.length|0; (i=(i-1)|0) >= 0;)
      S = (S + la[i|0])|0;
    return S;
  }
}

JS is untyped (dynamically typed), however:

asm.js is typed "bytecode" with deterministic performance

JS, a dynamically typed language, is often written with latent static types

Especially when "written" by compilers

Compiling to JS is not new

JS VMs compile to the metal

(just like Java but without declaring all types)

And the Java VM supports dynamic languages too:

from Mikhail Stoynov and Svetlin Nakov

The circle is now complete

WebAssembly

What does WebAssembly look like?

It is hard to see binary

enum class I32 : uint8_t {
  LitPool, LitImm, GetLoc, GetGlo, SetLoc, SetGlo,
  SLoad8, SLoadOff8, ULoad8, ULoadOff8,
  SLoad16, SLoadOff16, ULoad16, ULoadOff16,
  Load32, LoadOff32,
  Store8, StoreOff8, Store16, StoreOff16, Store32, StoreOff32,
  CallInt, CallInd, CallImp,
  Cond, Comma,
  FromF32, FromF64,
  Neg, Add, Sub, Mul, SDiv, UDiv, SMod, UMod,
  BitNot, BitOr, BitAnd, BitXor, Lsh, ArithRsh, LogicRsh,
  Clz,
  LogicNot,
  EqI32, EqF32, EqF64, NEqI32, NEqF32, NEqF64,
  SLeThI32, ULeThI32, LeThF32, LeThF64,
  ...
};
switch (i32) {
  ...
  case I32::FromF32: ...(s, prec, ctx, Result::NoIsh, Ctx::Default, "~~"); break;
  ak;
  case I32::FromF64: ...(s, prec, ctx, Result::NoIsh, Ctx::Default, "~~"); break;
  case I32::Neg:     ...(s, prec, ctx, Result::Intish, Ctx::Default, "-"); break;
  case I32::BitNot:  ...(s, prec, ctx, Result::NoIsh, Ctx::ToI32, "~"); break;
  ...
}

ES6 well-covered by other speakers

ES6/2015, ES7/2016, ES8...

Rapid(er) standards release process

ES7 async functions

function chainAnimationsPromise(elem, animations) {
  let ret = null;
  let p = currentPromise;
  for (let anim of animations) {
    p = p.then(function(val) {
      ret = val;
      return anim(elem);
    });
  }
  return p.catch(e => { /* ignore and keep going */ })
          .then(() => { return ret; });
}
function chainAnimationsGenerator(elem, animations) {
  return spawn(function*() {
    let ret = null;
    try {
      for (let anim of animations) {
        ret = yield anim(elem);
      }
    } catch(e) { /* ignore and keep going */ }
    return ret;
  });
}
async function chainAnimationsAsync(elem, animations) {
  let ret = null;
  try {
    for (let anim of animations) {
      ret = await anim(elem);
    }
  } catch(e) { /* ignore and keep going */ }
  return ret;
}

More on board for ES7+

Hygienic macros: Sweet.js

Demos