WEBVTT

00:00:00.000 --> 00:00:08.150 align:middle line:90%


00:00:08.150 --> 00:00:11.600 align:middle line:84%
This talk is a 40-year
history, beginning in 1995

00:00:11.600 --> 00:00:14.240 align:middle line:90%
and going until 2035.

00:00:14.240 --> 00:00:16.610 align:middle line:84%
In 1995, many of the
computers in the world

00:00:16.610 --> 00:00:18.060 align:middle line:90%
looked something like this.

00:00:18.060 --> 00:00:20.480 align:middle line:90%
This is Windows 95.

00:00:20.480 --> 00:00:21.980 align:middle line:84%
This is actually
the French version,

00:00:21.980 --> 00:00:26.330 align:middle line:84%
because screenshots are hard
to come by 40 years later.

00:00:26.330 --> 00:00:28.760 align:middle line:84%
On Windows 95, you could
run many different programs

00:00:28.760 --> 00:00:32.990 align:middle line:84%
including Netscape Navigator
2, which also came out in 1995.

00:00:32.990 --> 00:00:35.570 align:middle line:84%
Like many programs
on Windows 95,

00:00:35.570 --> 00:00:37.310 align:middle line:84%
it had a very long
splash screen,

00:00:37.310 --> 00:00:40.400 align:middle line:84%
but eventually, something
vaguely resembling a web

00:00:40.400 --> 00:00:43.070 align:middle line:90%
browser comes up.

00:00:43.070 --> 00:00:46.040 align:middle line:84%
Netscape Navigator was created
in a city called Mountain View.

00:00:46.040 --> 00:00:47.840 align:middle line:84%
This is on the
San Francisco Bay,

00:00:47.840 --> 00:00:51.230 align:middle line:84%
about 60 kilometers outside
of San Francisco itself.

00:00:51.230 --> 00:00:53.660 align:middle line:84%
Of course, today, both of these
are in the exclusion zone,

00:00:53.660 --> 00:00:59.330 align:middle line:84%
but at the time, this is where
much of the world's software

00:00:59.330 --> 00:00:59.930 align:middle line:90%
came from.

00:00:59.930 --> 00:01:03.200 align:middle line:90%


00:01:03.200 --> 00:01:06.590 align:middle line:84%
In May of 1995, a new
programming language

00:01:06.590 --> 00:01:08.330 align:middle line:90%
was designed in 10 days.

00:01:08.330 --> 00:01:10.220 align:middle line:84%
And to give you an idea
of how short 10 days

00:01:10.220 --> 00:01:12.478 align:middle line:84%
is, I'm going to zoom
out and compare this

00:01:12.478 --> 00:01:14.270 align:middle line:84%
to the amount of time
that Rich Hickey took

00:01:14.270 --> 00:01:16.955 align:middle line:84%
to design Clojure, which
was about 2 and 1/2 years.

00:01:16.955 --> 00:01:19.790 align:middle line:90%


00:01:19.790 --> 00:01:22.970 align:middle line:84%
In September of 1995,
Netscape 2 was released,

00:01:22.970 --> 00:01:24.800 align:middle line:84%
and included this new
programming language

00:01:24.800 --> 00:01:28.720 align:middle line:84%
that had been designed in only
10 days just months before.

00:01:28.720 --> 00:01:30.970 align:middle line:84%
As you would expect for
something designed in 10 days,

00:01:30.970 --> 00:01:32.600 align:middle line:84%
it had a lot of
unfortunate properties

00:01:32.600 --> 00:01:36.300 align:middle line:84%
like a single, unified number
type, no integers, only

00:01:36.300 --> 00:01:39.245 align:middle line:84%
IEEE 754 double-precision
floating point.

00:01:39.245 --> 00:01:41.120 align:middle line:84%
If you have a function
that takes an argument

00:01:41.120 --> 00:01:43.100 align:middle line:84%
and you omit the
argument, it will silently

00:01:43.100 --> 00:01:45.353 align:middle line:84%
do almost certainly
the wrong thing.

00:01:45.353 --> 00:01:46.770 align:middle line:84%
If you give it too
many arguments,

00:01:46.770 --> 00:01:49.100 align:middle line:90%
it will also do the wrong thing.

00:01:49.100 --> 00:01:52.410 align:middle line:84%
It doesn't have a true hash map
type, it has this object type.

00:01:52.410 --> 00:01:54.590 align:middle line:84%
So here, I have an
empty object, y.

00:01:54.590 --> 00:01:56.515 align:middle line:84%
I try to use an
empty array as a key,

00:01:56.515 --> 00:01:57.890 align:middle line:84%
and then when I
ask for the keys,

00:01:57.890 --> 00:01:59.557 align:middle line:84%
you can see I get
back the empty string.

00:01:59.557 --> 00:02:03.230 align:middle line:84%
So all keys are converted
into strings, which

00:02:03.230 --> 00:02:05.257 align:middle line:90%
is usually not what you want.

00:02:05.257 --> 00:02:07.340 align:middle line:84%
And finally, it just has
lots of bizarre behavior,

00:02:07.340 --> 00:02:09.482 align:middle line:84%
like if you map parseInt
over strings of integers,

00:02:09.482 --> 00:02:10.190 align:middle line:90%
you get nonsense.

00:02:10.190 --> 00:02:14.560 align:middle line:90%


00:02:14.560 --> 00:02:18.340 align:middle line:84%
My name is Gary Bernhardt,
and the title of this talk

00:02:18.340 --> 00:02:21.640 align:middle line:84%
is the birth and
death of JavaScript.

00:02:21.640 --> 00:02:31.050 align:middle line:84%
Now, we just saw
some ancient history,

00:02:31.050 --> 00:02:34.140 align:middle line:84%
and I'm going to skip
passed a lot of time

00:02:34.140 --> 00:02:36.810 align:middle line:84%
because nothing really
interesting happens until 2008.

00:02:36.810 --> 00:02:39.070 align:middle line:84%
Before 2008, this language
is basically a joke.

00:02:39.070 --> 00:02:40.800 align:middle line:90%
No one wants to program in it.

00:02:40.800 --> 00:02:43.910 align:middle line:84%
You write 50 lines of it
for some trivial behavior

00:02:43.910 --> 00:02:47.760 align:middle line:84%
in your website, but no one
was really taking it seriously.

00:02:47.760 --> 00:02:50.707 align:middle line:84%
The big marker for people
beginning to take it seriously

00:02:50.707 --> 00:02:51.540 align:middle line:90%
is the "JavaScript--

00:02:51.540 --> 00:02:53.670 align:middle line:84%
The Good Parts"
by Doug Crockford.

00:02:53.670 --> 00:02:57.480 align:middle line:84%
This is an attempt to carve out
a subset of the language that

00:02:57.480 --> 00:03:00.420 align:middle line:84%
can actually be used to
build working software.

00:03:00.420 --> 00:03:05.970 align:middle line:84%
It is a very small book, but
it does represent the beginning

00:03:05.970 --> 00:03:08.010 align:middle line:84%
of the culture as
a whole starting

00:03:08.010 --> 00:03:10.620 align:middle line:84%
to take a language a
little bit more seriously.

00:03:10.620 --> 00:03:12.390 align:middle line:84%
One year after
this, in 2009, you

00:03:12.390 --> 00:03:15.360 align:middle line:84%
get Node, which is basically
a set of asynchronous IO

00:03:15.360 --> 00:03:18.120 align:middle line:84%
libraries married to a
JavaScript virtual machine,

00:03:18.120 --> 00:03:20.610 align:middle line:90%
distributed as a single package.

00:03:20.610 --> 00:03:23.838 align:middle line:84%
And the main reason
that many people

00:03:23.838 --> 00:03:25.380 align:middle line:84%
were so excited
about this is that it

00:03:25.380 --> 00:03:27.030 align:middle line:84%
allowed you to run
the same language

00:03:27.030 --> 00:03:28.350 align:middle line:90%
on the client and the server.

00:03:28.350 --> 00:03:29.710 align:middle line:84%
You only had one
choice on the client,

00:03:29.710 --> 00:03:31.168 align:middle line:84%
so if you want to
run one language,

00:03:31.168 --> 00:03:33.930 align:middle line:84%
you have to use JavaScript
on the server, as well.

00:03:33.930 --> 00:03:35.460 align:middle line:84%
It had some
unfortunate properties,

00:03:35.460 --> 00:03:38.670 align:middle line:84%
like encouraging highly
nested callbacks.

00:03:38.670 --> 00:03:41.460 align:middle line:84%
Now, some apologists
at the time would

00:03:41.460 --> 00:03:43.980 align:middle line:84%
have said that this is the
programmer's fault for using it

00:03:43.980 --> 00:03:45.300 align:middle line:90%
in this way--

00:03:45.300 --> 00:03:48.660 align:middle line:84%
a timeless argument
that is always wrong.

00:03:48.660 --> 00:03:53.340 align:middle line:84%
My own view is that the behavior
you see a tool being used for

00:03:53.340 --> 00:03:55.860 align:middle line:84%
is the behavior that
that tool encourages,

00:03:55.860 --> 00:03:59.070 align:middle line:84%
and Node encourages
highly nested callbacks.

00:03:59.070 --> 00:04:02.340 align:middle line:84%
Nonetheless, many people were
very excited about it, mostly--

00:04:02.340 --> 00:04:04.410 align:middle line:84%
at least initially--
because it allowed

00:04:04.410 --> 00:04:06.000 align:middle line:90%
them to use a single language.

00:04:06.000 --> 00:04:09.130 align:middle line:84%
At the same time, many
people were not so excited.

00:04:09.130 --> 00:04:10.593 align:middle line:90%
And I have a quote here--

00:04:10.593 --> 00:04:12.510 align:middle line:84%
"Node is a tumor on the
programming community,

00:04:12.510 --> 00:04:14.310 align:middle line:84%
in that not only is it
completely braindead,

00:04:14.310 --> 00:04:16.727 align:middle line:84%
but the people who use it go
on to infect other people who

00:04:16.727 --> 00:04:19.079 align:middle line:90%
can't think for themselves."

00:04:19.079 --> 00:04:22.620 align:middle line:84%
Not a glowing review of
this programming tool.

00:04:22.620 --> 00:04:25.320 align:middle line:84%
I've left this unattributed
because the author

00:04:25.320 --> 00:04:27.270 align:middle line:84%
of this quote has
since disavowed

00:04:27.270 --> 00:04:28.890 align:middle line:90%
this style of discourse.

00:04:28.890 --> 00:04:31.022 align:middle line:84%
That author was
not me, by the way.

00:04:31.022 --> 00:04:32.730 align:middle line:84%
But nonetheless, you
can see that there's

00:04:32.730 --> 00:04:36.420 align:middle line:84%
a highly divided opinion about
Node and about JavaScript

00:04:36.420 --> 00:04:37.260 align:middle line:90%
in general.

00:04:37.260 --> 00:04:39.000 align:middle line:84%
And in the midst of
this, in this culture

00:04:39.000 --> 00:04:42.492 align:middle line:84%
of this very strong
division in opinion,

00:04:42.492 --> 00:04:44.700 align:middle line:84%
JavaScript becomes the
most-used programming language

00:04:44.700 --> 00:04:47.190 align:middle line:90%
in the world.

00:04:47.190 --> 00:04:51.460 align:middle line:84%
This brings us to the teens,
and specifically 2013.

00:04:51.460 --> 00:04:56.070 align:middle line:84%
In 2013, you get the release
and initial sort of discussion

00:04:56.070 --> 00:04:59.910 align:middle line:84%
around a tool
called ASM, ASM.js.

00:04:59.910 --> 00:05:03.000 align:middle line:84%
It is a subset of the JavaScript
language designed to compile

00:05:03.000 --> 00:05:05.360 align:middle line:90%
very closely to native code.

00:05:05.360 --> 00:05:07.110 align:middle line:84%
And I have a couple
of very short examples

00:05:07.110 --> 00:05:09.340 align:middle line:84%
just so we can see
what it looks like.

00:05:09.340 --> 00:05:11.860 align:middle line:84%
This is a function that
adds 1 to integers.

00:05:11.860 --> 00:05:13.690 align:middle line:84%
Now, JavaScript
doesn't have integers,

00:05:13.690 --> 00:05:15.790 align:middle line:84%
and we'll get to
that in a second,

00:05:15.790 --> 00:05:17.260 align:middle line:84%
but that's all
this function does.

00:05:17.260 --> 00:05:20.340 align:middle line:84%
And you can see the first thing
it actually does is binary

00:05:20.340 --> 00:05:22.590 align:middle line:90%
or its argument with 0.

00:05:22.590 --> 00:05:25.950 align:middle line:84%
Now, that doesn't have any
meaning in most languages

00:05:25.950 --> 00:05:29.190 align:middle line:84%
because binary or with 0 gives
you what you started with.

00:05:29.190 --> 00:05:31.480 align:middle line:84%
But this is actually
a type annotation,

00:05:31.480 --> 00:05:33.510 align:middle line:84%
so what you're saying to
the ASM virtual machine

00:05:33.510 --> 00:05:36.900 align:middle line:84%
here is that x is actually an
integer because binary or only

00:05:36.900 --> 00:05:39.110 align:middle line:90%
makes sense on integers.

00:05:39.110 --> 00:05:41.520 align:middle line:84%
In a normal JavaScript
VM, this would actually

00:05:41.520 --> 00:05:43.857 align:middle line:84%
convert from a float into
an integer, do the binary

00:05:43.857 --> 00:05:45.440 align:middle line:84%
or, and then convert
back into a float

00:05:45.440 --> 00:05:47.995 align:middle line:90%
because all numbers are floats.

00:05:47.995 --> 00:05:49.620 align:middle line:84%
In any case, this is
a type annotation,

00:05:49.620 --> 00:05:52.090 align:middle line:84%
and you see the same
thing on the return value.

00:05:52.090 --> 00:05:54.900 align:middle line:84%
What this allows the
ASM compiler to do

00:05:54.900 --> 00:05:57.660 align:middle line:84%
is to emit a single
CPU instruction

00:05:57.660 --> 00:06:00.060 align:middle line:84%
for the body of this function,
which is an integer add.

00:06:00.060 --> 00:06:02.550 align:middle line:84%
Whereas a normal JavaScript
VM in the naive case

00:06:02.550 --> 00:06:05.280 align:middle line:84%
would have to do all kinds of
type checking, in, sort of,

00:06:05.280 --> 00:06:07.500 align:middle line:84%
the less-naive case
would have to JIT,

00:06:07.500 --> 00:06:09.570 align:middle line:84%
an ASM compiler can just
compile this straight

00:06:09.570 --> 00:06:12.210 align:middle line:90%
into a single instruction.

00:06:12.210 --> 00:06:13.590 align:middle line:84%
Here's a slightly
larger example,

00:06:13.590 --> 00:06:15.870 align:middle line:84%
and we're just going to look
at the two functions that

00:06:15.870 --> 00:06:16.677 align:middle line:90%
are the meat here.

00:06:16.677 --> 00:06:19.260 align:middle line:84%
There's a square function that
squares floating point numbers.

00:06:19.260 --> 00:06:21.635 align:middle line:84%
And you can tell they're floats
because the argument gets

00:06:21.635 --> 00:06:24.200 align:middle line:84%
assigned to plus itself, a
unary plus, which is the type

00:06:24.200 --> 00:06:26.130 align:middle line:90%
notation for floating point.

00:06:26.130 --> 00:06:29.490 align:middle line:84%
The diagonal distance
function, the second function,

00:06:29.490 --> 00:06:31.013 align:middle line:90%
does the same thing--

00:06:31.013 --> 00:06:32.430 align:middle line:84%
annotates both of
its arguments as

00:06:32.430 --> 00:06:36.390 align:middle line:84%
floats and its return
value as a float.

00:06:36.390 --> 00:06:39.480 align:middle line:84%
Now, you don't want to
program in this way, right?

00:06:39.480 --> 00:06:42.300 align:middle line:84%
This would be horrible to have
to annotate all your arguments

00:06:42.300 --> 00:06:43.630 align:middle line:90%
and return values this way.

00:06:43.630 --> 00:06:45.990 align:middle line:84%
However, computers are
really good at doing things

00:06:45.990 --> 00:06:49.050 align:middle line:84%
100% of the time,
and here, I have

00:06:49.050 --> 00:06:52.470 align:middle line:84%
the beginning, the preamble,
of the CPython virtual machine

00:06:52.470 --> 00:06:55.920 align:middle line:90%
compiled from C into ASM.

00:06:55.920 --> 00:06:59.460 align:middle line:84%
This is about, I think, 3
megabytes of ASM code compiled.

00:06:59.460 --> 00:07:01.900 align:middle line:84%
It's the entire CPython
virtual machine.

00:07:01.900 --> 00:07:04.590 align:middle line:84%
It has the compiler in
there, it has the runtime,

00:07:04.590 --> 00:07:09.390 align:middle line:84%
it has the garbage collector--
all of that compiled into ASM.

00:07:09.390 --> 00:07:10.860 align:middle line:84%
And this will work
in any browser

00:07:10.860 --> 00:07:13.420 align:middle line:84%
with a correct JavaScript
implementation,

00:07:13.420 --> 00:07:16.935 align:middle line:84%
so it is backwards
compatible with JavaScript.

00:07:16.935 --> 00:07:18.810 align:middle line:84%
Just to show you that
this does actually work

00:07:18.810 --> 00:07:21.750 align:middle line:84%
and did actually work
in 2013, all my demos

00:07:21.750 --> 00:07:25.620 align:middle line:90%
are going to be 2013 technology.

00:07:25.620 --> 00:07:27.880 align:middle line:84%
I have a Repl here
running in a browser,

00:07:27.880 --> 00:07:30.180 align:middle line:84%
and if I do hello,
world in it, you

00:07:30.180 --> 00:07:32.157 align:middle line:84%
can see that it
does, in fact, work.

00:07:32.157 --> 00:07:34.740 align:middle line:84%
Now, of course, you're not going
to use this for real software

00:07:34.740 --> 00:07:36.073 align:middle line:90%
because it's 3 megabytes of ASM.

00:07:36.073 --> 00:07:37.530 align:middle line:90%
It's too big.

00:07:37.530 --> 00:07:39.270 align:middle line:84%
And it's just sort of
a curiosity, right?

00:07:39.270 --> 00:07:42.960 align:middle line:84%
It's neat to run a
VM in a web browser.

00:07:42.960 --> 00:07:46.140 align:middle line:84%
But here's something a
little bit more convincing.

00:07:46.140 --> 00:07:48.390 align:middle line:84%
This is the Unreal
Engine 3 game engine,

00:07:48.390 --> 00:07:50.790 align:middle line:84%
which was used for high-end
games in the early-

00:07:50.790 --> 00:07:52.080 align:middle line:90%
to mid-teens.

00:07:52.080 --> 00:07:55.200 align:middle line:84%
And this is a short screencast
of it running inside

00:07:55.200 --> 00:07:56.788 align:middle line:90%
of Firefox.

00:07:56.788 --> 00:07:58.830 align:middle line:84%
The last demo, the Python
demo, is running inside

00:07:58.830 --> 00:08:01.110 align:middle line:84%
of Chrome, which does
not support ASM natively.

00:08:01.110 --> 00:08:03.990 align:middle line:84%
That was actually running
as pure JavaScript.

00:08:03.990 --> 00:08:09.300 align:middle line:84%
And here, you see a video game
engine running at a perfectly

00:08:09.300 --> 00:08:11.460 align:middle line:84%
playable frame rate--
not 60 frames per second,

00:08:11.460 --> 00:08:12.600 align:middle line:90%
but playable--

00:08:12.600 --> 00:08:15.900 align:middle line:84%
inside of a web browser,
and all of this is ASM.

00:08:15.900 --> 00:08:19.140 align:middle line:84%
So that was a quarter
million lines of C code,

00:08:19.140 --> 00:08:22.140 align:middle line:84%
arbitrary C code-- there's
surely pointer math going

00:08:22.140 --> 00:08:24.060 align:middle line:90%
on in there somewhere--

00:08:24.060 --> 00:08:29.240 align:middle line:84%
compiled to ASM, running
inside of a web browser in 2013

00:08:29.240 --> 00:08:32.760 align:middle line:84%
at about half-speed,
compared to running natively.

00:08:32.760 --> 00:08:35.760 align:middle line:84%
Now, the fact that in the
year that ASM was released

00:08:35.760 --> 00:08:38.700 align:middle line:84%
you could run a video game
engine inside of a web browser

00:08:38.700 --> 00:08:42.673 align:middle line:84%
at half of native speed is in
and of itself very impressive.

00:08:42.673 --> 00:08:44.340 align:middle line:84%
It's also more
impressive that that port

00:08:44.340 --> 00:08:47.910 align:middle line:84%
was done in five days
through a joint venture

00:08:47.910 --> 00:08:50.610 align:middle line:84%
through Epic, which created
Unreal, and Mozilla, which

00:08:50.610 --> 00:08:53.550 align:middle line:90%
created Firefox.

00:08:53.550 --> 00:08:56.100 align:middle line:84%
For me, the most
interesting thing here

00:08:56.100 --> 00:08:59.310 align:middle line:84%
is not that I can run a VM or
a video game in my web browser,

00:08:59.310 --> 00:09:03.287 align:middle line:84%
it's that now I can have
integers again because I can

00:09:03.287 --> 00:09:05.370 align:middle line:84%
write code that emits
native integer instructions,

00:09:05.370 --> 00:09:08.760 align:middle line:84%
and on top of that, I can
build bignums, and with this,

00:09:08.760 --> 00:09:12.390 align:middle line:84%
sort of, low-level binding,
I can build a real hash map.

00:09:12.390 --> 00:09:15.000 align:middle line:84%
I can fix all of these features
of programming languages

00:09:15.000 --> 00:09:17.625 align:middle line:84%
that have existed for as long as
languages have but are somehow

00:09:17.625 --> 00:09:20.400 align:middle line:90%
missing from JavaScript.

00:09:20.400 --> 00:09:24.660 align:middle line:84%
This brings us to
the late teens.

00:09:24.660 --> 00:09:26.790 align:middle line:84%
It took a few years for
the tooling around ASM

00:09:26.790 --> 00:09:27.780 align:middle line:90%
to sort of spin up.

00:09:27.780 --> 00:09:31.020 align:middle line:84%
It took a few years for people
to kind of get familiar with it

00:09:31.020 --> 00:09:33.090 align:middle line:84%
and start really
building stuff with it.

00:09:33.090 --> 00:09:35.820 align:middle line:84%
And in the late teens, you start
to see software development

00:09:35.820 --> 00:09:37.800 align:middle line:84%
tools ported first,
obviously, because we're

00:09:37.800 --> 00:09:39.570 align:middle line:90%
selfish like any other human.

00:09:39.570 --> 00:09:43.100 align:middle line:84%
So here, you see the Z shell
running inside of Chrome.

00:09:43.100 --> 00:09:44.850 align:middle line:84%
The Z shell, for anyone
who's not used it,

00:09:44.850 --> 00:09:47.040 align:middle line:90%
is a Unix shell like bash--

00:09:47.040 --> 00:09:49.110 align:middle line:90%
mostly bash-compatible.

00:09:49.110 --> 00:09:52.970 align:middle line:84%
Of course, I can run an editor
from my shell inside of my web

00:09:52.970 --> 00:09:53.470 align:middle line:90%
browser.

00:09:53.470 --> 00:09:57.190 align:middle line:84%
I can background that editor
because this is the full shell,

00:09:57.190 --> 00:10:00.090 align:middle line:90%
including job control.

00:10:00.090 --> 00:10:02.820 align:middle line:84%
And I can do all the other
stuff you would expect.

00:10:02.820 --> 00:10:04.980 align:middle line:90%
And, in fact, wait a minute.

00:10:04.980 --> 00:10:07.740 align:middle line:84%
What language is a C
compiler written in?

00:10:07.740 --> 00:10:11.638 align:middle line:84%
Well, any respectable
compiler is written

00:10:11.638 --> 00:10:12.930 align:middle line:90%
in the language it's compiling.

00:10:12.930 --> 00:10:14.190 align:middle line:90%
It's self-hosting.

00:10:14.190 --> 00:10:18.060 align:middle line:84%
So we can run a C compiler
inside the shell inside the web

00:10:18.060 --> 00:10:19.090 align:middle line:90%
browser.

00:10:19.090 --> 00:10:22.320 align:middle line:84%
And if I whack Enter, it
just compiled that hello.c

00:10:22.320 --> 00:10:25.650 align:middle line:84%
not into native
binary, but into ASM.

00:10:25.650 --> 00:10:28.200 align:middle line:84%
And if I run the, quote unquote,
"binary," which is really

00:10:28.200 --> 00:10:31.110 align:middle line:84%
just a blob of ASM, it will
do exactly what you expect

00:10:31.110 --> 00:10:34.080 align:middle line:90%
and print hello, world.

00:10:34.080 --> 00:10:35.880 align:middle line:84%
Running a compiler
inside of a web browser

00:10:35.880 --> 00:10:38.890 align:middle line:84%
is completely
unsurprising once you

00:10:38.890 --> 00:10:41.070 align:middle line:84%
know a compiler to that
target exists, right?

00:10:41.070 --> 00:10:43.530 align:middle line:84%
Once there's a compiler
that can compile into ASM,

00:10:43.530 --> 00:10:45.690 align:middle line:84%
and ASM is backwards
compatible with JavaScript,

00:10:45.690 --> 00:10:48.060 align:middle line:84%
you can run anything
inside of a web browser.

00:10:48.060 --> 00:10:51.030 align:middle line:90%


00:10:51.030 --> 00:10:55.350 align:middle line:84%
At this point in history, as
we all know, war was happening.

00:10:55.350 --> 00:10:59.490 align:middle line:84%
And for those five years,
not a lot of progress

00:10:59.490 --> 00:11:02.710 align:middle line:90%
was made, as you would expect.

00:11:02.710 --> 00:11:06.070 align:middle line:84%
So until about 2025, nothing
was really happening.

00:11:06.070 --> 00:11:10.140 align:middle line:84%
And my own take on
this is that we may not

00:11:10.140 --> 00:11:12.880 align:middle line:84%
have been programming as we
were running for our lives.

00:11:12.880 --> 00:11:14.902 align:middle line:84%
And if you're one of
40 million refugees

00:11:14.902 --> 00:11:16.860 align:middle line:84%
off the coast of Australia,
you're probably not

00:11:16.860 --> 00:11:18.420 align:middle line:90%
doing a lot of programming.

00:11:18.420 --> 00:11:23.460 align:middle line:84%
However, what you are doing is
way deep in your subconscious,

00:11:23.460 --> 00:11:25.290 align:middle line:84%
you are releasing the
emotional attachments

00:11:25.290 --> 00:11:27.960 align:middle line:84%
you had to those old
programming tools.

00:11:27.960 --> 00:11:34.750 align:middle line:84%
And I think that after these
five years, when we come back,

00:11:34.750 --> 00:11:39.100 align:middle line:84%
the reason that we saw
such a huge acceleration

00:11:39.100 --> 00:11:42.650 align:middle line:84%
in the rate of adoption of
this stuff is exactly that.

00:11:42.650 --> 00:11:44.590 align:middle line:84%
So that takes us
to 2025 when you

00:11:44.590 --> 00:11:48.640 align:middle line:84%
start to see thick, extremely
large applications ported

00:11:48.640 --> 00:11:50.740 align:middle line:90%
into ASM.

00:11:50.740 --> 00:11:53.650 align:middle line:84%
Here, I have a screenshot
of the GIMP, the new image

00:11:53.650 --> 00:11:55.460 align:middle line:90%
manipulation program.

00:11:55.460 --> 00:11:58.090 align:middle line:84%
It's an image editing program
that some of you who are older

00:11:58.090 --> 00:12:01.750 align:middle line:84%
might have seen, and it is
running here inside of Chrome.

00:12:01.750 --> 00:12:05.070 align:middle line:84%
Now, if you have a good memory
for archaic operating system

00:12:05.070 --> 00:12:07.010 align:middle line:84%
widgets, you may notice
that this is actually

00:12:07.010 --> 00:12:09.520 align:middle line:84%
the Windows version of the
GIMP running inside the Mac

00:12:09.520 --> 00:12:14.560 align:middle line:84%
version of Chrome, so there are
several questions raised here.

00:12:14.560 --> 00:12:16.560 align:middle line:84%
What's happening is that
we have the GIMP, which

00:12:16.560 --> 00:12:19.170 align:middle line:90%
is a huge pile of C code.

00:12:19.170 --> 00:12:21.012 align:middle line:84%
And it wants to talk
to the Win32 API

00:12:21.012 --> 00:12:22.470 align:middle line:84%
because it's a
Windows application,

00:12:22.470 --> 00:12:24.820 align:middle line:84%
but, of course, Win32
is closed-source,

00:12:24.820 --> 00:12:27.240 align:middle line:84%
so we can't just
compile it into ASM.

00:12:27.240 --> 00:12:29.010 align:middle line:84%
So instead, we need
a reimplementation.

00:12:29.010 --> 00:12:32.100 align:middle line:84%
And fortunately, since the '90s,
there has been a thing called

00:12:32.100 --> 00:12:34.680 align:middle line:84%
Wine, which is a
reimplementation of Win32--

00:12:34.680 --> 00:12:37.620 align:middle line:90%
also a giant pile of C code.

00:12:37.620 --> 00:12:39.480 align:middle line:84%
Now our problem
is that Wine wants

00:12:39.480 --> 00:12:43.020 align:middle line:84%
to talk X Windows because
it's an X Windows system.

00:12:43.020 --> 00:12:46.320 align:middle line:84%
We don't have X Windows, but
we do have an X Windows shim.

00:12:46.320 --> 00:12:49.800 align:middle line:84%
And we take all of these things,
all of which are written in C,

00:12:49.800 --> 00:12:52.350 align:middle line:84%
compile them from C
into ASM, and then

00:12:52.350 --> 00:12:57.960 align:middle line:84%
that giant blob of code is
run inside of Google Chrome.

00:12:57.960 --> 00:12:59.700 align:middle line:84%
And once again, basic
compilers, right?

00:12:59.700 --> 00:13:02.340 align:middle line:84%
Once you have a C compiler,
you can compile any C code,

00:13:02.340 --> 00:13:04.980 align:middle line:84%
and pretty much everything
is written in C.

00:13:04.980 --> 00:13:08.950 align:middle line:84%
But wait, what language
is Chrome written in?

00:13:08.950 --> 00:13:12.465 align:middle line:84%
C. So here's the GIMP
running inside Chrome

00:13:12.465 --> 00:13:13.590 align:middle line:90%
with Chrome inside Firefox.

00:13:13.590 --> 00:13:17.990 align:middle line:90%


00:13:17.990 --> 00:13:18.830 align:middle line:90%
It's just compilers.

00:13:18.830 --> 00:13:21.320 align:middle line:84%
Once you have a
compiler, all you need

00:13:21.320 --> 00:13:24.150 align:middle line:90%
is the libraries being used.

00:13:24.150 --> 00:13:26.870 align:middle line:84%
So here, what we have is the
GIMP running against Wine

00:13:26.870 --> 00:13:28.640 align:middle line:84%
running against
an X Windows shim

00:13:28.640 --> 00:13:31.460 align:middle line:90%
all compiled from C into ASM.

00:13:31.460 --> 00:13:32.840 align:middle line:90%
That ASM is running on Chrome.

00:13:32.840 --> 00:13:35.580 align:middle line:84%
And now we have another
Wine-like problem,

00:13:35.580 --> 00:13:38.210 align:middle line:84%
which is that was the
Mac version of Chrome

00:13:38.210 --> 00:13:40.130 align:middle line:84%
running inside of a
Mac version of Firefox.

00:13:40.130 --> 00:13:42.860 align:middle line:84%
But the Mac windowing
stuff is all closed-source,

00:13:42.860 --> 00:13:45.650 align:middle line:84%
so we had to do what we did in
the '90s and reimplement it.

00:13:45.650 --> 00:13:47.360 align:middle line:84%
And because we like
confusing names,

00:13:47.360 --> 00:13:50.690 align:middle line:84%
the open-source implementation
of Cocoa is called Cacao.

00:13:50.690 --> 00:13:53.480 align:middle line:90%


00:13:53.480 --> 00:13:58.790 align:middle line:84%
And then Cacao and Chrome are
both compiled from C into ASM,

00:13:58.790 --> 00:14:01.240 align:middle line:84%
and all of that is
running inside of Firefox.

00:14:01.240 --> 00:14:03.710 align:middle line:84%
Now, we're not talking
about something

00:14:03.710 --> 00:14:05.840 align:middle line:90%
you would actually want to do.

00:14:05.840 --> 00:14:07.940 align:middle line:84%
This is several hundred
megabytes of ASM code.

00:14:07.940 --> 00:14:09.648 align:middle line:84%
It is not the fastest
thing in the world,

00:14:09.648 --> 00:14:14.440 align:middle line:84%
but it does work, because
it's just compilers.

00:14:14.440 --> 00:14:17.410 align:middle line:84%
Now we have to take
a brief digression

00:14:17.410 --> 00:14:20.050 align:middle line:84%
into how computers
actually work to understand

00:14:20.050 --> 00:14:21.950 align:middle line:90%
the next stage in history.

00:14:21.950 --> 00:14:25.000 align:middle line:84%
So I apologize for talking
about basic things.

00:14:25.000 --> 00:14:27.250 align:middle line:84%
They're going to be four
very quick lessons, the first

00:14:27.250 --> 00:14:30.140 align:middle line:90%
of which is virtual memory.

00:14:30.140 --> 00:14:32.650 align:middle line:84%
In a computer system, you have
all these processes running,

00:14:32.650 --> 00:14:34.840 align:middle line:84%
and you have the
kernel, and ideally, you

00:14:34.840 --> 00:14:36.790 align:middle line:84%
would like a process
like Vim to be

00:14:36.790 --> 00:14:38.980 align:middle line:84%
unable to corrupt
the kernel's memory

00:14:38.980 --> 00:14:41.050 align:middle line:90%
and crash the entire system.

00:14:41.050 --> 00:14:42.820 align:middle line:84%
Also, for simplicity,
it would be nice

00:14:42.820 --> 00:14:45.880 align:middle line:84%
if every program thought it
had the entire memory space

00:14:45.880 --> 00:14:48.890 align:middle line:84%
and could just start at
address 0 and go up from there.

00:14:48.890 --> 00:14:52.030 align:middle line:84%
The problem is that there's
only one physical memory, right?

00:14:52.030 --> 00:14:55.870 align:middle line:84%
There's only one true
address 0 on a chip.

00:14:55.870 --> 00:14:58.300 align:middle line:84%
So what we do is as these
programs start allocating

00:14:58.300 --> 00:15:00.520 align:middle line:84%
memory, we map them
onto the physical memory

00:15:00.520 --> 00:15:01.660 align:middle line:90%
in a sort of arbitrary way.

00:15:01.660 --> 00:15:04.960 align:middle line:84%
It's not necessarily
monotonic or contiguous,

00:15:04.960 --> 00:15:06.788 align:middle line:90%
there's no real guarantees.

00:15:06.788 --> 00:15:08.080 align:middle line:90%
It's just an arbitrary mapping.

00:15:08.080 --> 00:15:09.550 align:middle line:90%
It's a level of indirection.

00:15:09.550 --> 00:15:11.680 align:middle line:84%
So inside of a computer,
every single memory lookup

00:15:11.680 --> 00:15:13.300 align:middle line:84%
has to go through a
table that maps it

00:15:13.300 --> 00:15:17.350 align:middle line:90%
to the actual physical address.

00:15:17.350 --> 00:15:19.840 align:middle line:84%
That stops Vim from
crashing the kernel,

00:15:19.840 --> 00:15:21.460 align:middle line:90%
crashing other programs.

00:15:21.460 --> 00:15:24.930 align:middle line:84%
But now, obviously there's some
mechanism for setting this up,

00:15:24.930 --> 00:15:25.430 align:middle line:90%
right?

00:15:25.430 --> 00:15:27.222 align:middle line:84%
There's some way to
configure this mapping,

00:15:27.222 --> 00:15:29.592 align:middle line:84%
so Vim can just use that
mechanism to map kernel memory

00:15:29.592 --> 00:15:31.300 align:middle line:84%
into its own memory
space, and now you're

00:15:31.300 --> 00:15:32.750 align:middle line:90%
back where you started.

00:15:32.750 --> 00:15:35.200 align:middle line:84%
So you need a secondary
protection mechanism

00:15:35.200 --> 00:15:37.360 align:middle line:90%
called a protection ring.

00:15:37.360 --> 00:15:39.623 align:middle line:84%
Most programs-- in fact,
probably most of the software

00:15:39.623 --> 00:15:42.040 align:middle line:84%
that most of the people in
this room have ever worked oh--

00:15:42.040 --> 00:15:43.570 align:middle line:84%
run in what's
called ring 3, which

00:15:43.570 --> 00:15:45.610 align:middle line:84%
is just where
userland programs run.

00:15:45.610 --> 00:15:49.120 align:middle line:84%
You cannot touch hardware, you
cannot manipulate the virtual

00:15:49.120 --> 00:15:50.590 align:middle line:90%
memory mappings.

00:15:50.590 --> 00:15:53.080 align:middle line:84%
The kernel runs in a superset
of ring 3 called the ring

00:15:53.080 --> 00:15:56.280 align:middle line:84%
0 where you can do
all those evil things.

00:15:56.280 --> 00:16:00.170 align:middle line:84%
And rings 1 and 2 are
not really used anymore.

00:16:00.170 --> 00:16:03.070 align:middle line:84%
So now, we can put Vim
in its own address space,

00:16:03.070 --> 00:16:06.160 align:middle line:84%
we can disallow it from changing
that address space mapping,

00:16:06.160 --> 00:16:10.480 align:middle line:84%
and this protects everyone
from everyone else.

00:16:10.480 --> 00:16:13.540 align:middle line:84%
Moving on from memory, lesson
3 is a really easy one--

00:16:13.540 --> 00:16:15.160 align:middle line:90%
a function call.

00:16:15.160 --> 00:16:16.630 align:middle line:84%
The problem with
the CPU is that it

00:16:16.630 --> 00:16:18.710 align:middle line:84%
is a highly stateful,
complex device,

00:16:18.710 --> 00:16:21.940 align:middle line:84%
and when you call a
function, that function

00:16:21.940 --> 00:16:24.678 align:middle line:84%
is going to use the registers
which you are currently using.

00:16:24.678 --> 00:16:27.220 align:middle line:84%
So to call a function, you have
to take all of your registers

00:16:27.220 --> 00:16:29.350 align:middle line:84%
and push them onto a
stack, and once you've

00:16:29.350 --> 00:16:31.840 align:middle line:84%
done that, you can jump to
the function you want to call.

00:16:31.840 --> 00:16:36.080 align:middle line:84%
And it's that function's job
to jump back to you at the end.

00:16:36.080 --> 00:16:39.610 align:middle line:84%
So that's really simple, but
what about a system call,

00:16:39.610 --> 00:16:41.650 align:middle line:84%
which is something like
open or read or write,

00:16:41.650 --> 00:16:43.030 align:middle line:84%
anything that
needs to be handled

00:16:43.030 --> 00:16:46.270 align:middle line:84%
by the kernel, anything that has
to ultimately touch hardware?

00:16:46.270 --> 00:16:48.212 align:middle line:84%
Well, you can't
jump into the kernel

00:16:48.212 --> 00:16:50.170 align:middle line:84%
because the kernel's
memory space is completely

00:16:50.170 --> 00:16:51.730 align:middle line:90%
separate from your program.

00:16:51.730 --> 00:16:53.230 align:middle line:90%
There's no place to jump to.

00:16:53.230 --> 00:16:56.140 align:middle line:84%
There is no memory address that
you know of that could possibly

00:16:56.140 --> 00:16:57.760 align:middle line:90%
be jumped to.

00:16:57.760 --> 00:17:00.370 align:middle line:84%
So first of all, you still
have to push your registers,

00:17:00.370 --> 00:17:02.410 align:middle line:84%
like pretty much
everything in a computer

00:17:02.410 --> 00:17:04.390 align:middle line:90%
involves pushing your registers.

00:17:04.390 --> 00:17:06.550 align:middle line:84%
And instead of jumping,
you fire an interrupt.

00:17:06.550 --> 00:17:10.020 align:middle line:84%
And traditionally, on x86,
this was interrupt 0x80.

00:17:10.020 --> 00:17:12.700 align:middle line:84%
Later, other
mechanisms showed up.

00:17:12.700 --> 00:17:15.310 align:middle line:84%
The kernel has previously
registered an interrupt handler

00:17:15.310 --> 00:17:17.710 align:middle line:84%
for that, so it's going
to trap that interrupt.

00:17:17.710 --> 00:17:20.530 align:middle line:84%
And as part of the
handling of that interrupt,

00:17:20.530 --> 00:17:23.470 align:middle line:84%
there's going to be a switch
to ring 0 from ring 3,

00:17:23.470 --> 00:17:26.140 align:middle line:84%
and there's going to be a switch
in the virtual memory tables

00:17:26.140 --> 00:17:28.870 align:middle line:84%
so that we're in kernel address
space, not userland address

00:17:28.870 --> 00:17:29.920 align:middle line:90%
space.

00:17:29.920 --> 00:17:34.660 align:middle line:84%
And now we can jump to the
handler for that system call.

00:17:34.660 --> 00:17:38.440 align:middle line:84%
And this is all happening every
time you read from a socket

00:17:38.440 --> 00:17:41.620 align:middle line:84%
or do pretty much
anything in a computer.

00:17:41.620 --> 00:17:44.410 align:middle line:84%
Now, the four things
I've not dimmed out here

00:17:44.410 --> 00:17:46.360 align:middle line:90%
are all pure overhead.

00:17:46.360 --> 00:17:48.360 align:middle line:84%
None of this is what
you wanted to do.

00:17:48.360 --> 00:17:49.870 align:middle line:84%
You wanted to read
from a socket.

00:17:49.870 --> 00:17:51.660 align:middle line:84%
You don't care about switching
virtual memory tables,

00:17:51.660 --> 00:17:53.285 align:middle line:84%
you don't care about
protection rings--

00:17:53.285 --> 00:17:55.120 align:middle line:84%
that's all, sort
of, implementation

00:17:55.120 --> 00:17:57.130 align:middle line:84%
detail that has to be
there but you don't truly

00:17:57.130 --> 00:17:59.800 align:middle line:84%
care about as the programmer,
as long as you get your safety

00:17:59.800 --> 00:18:02.273 align:middle line:90%
guarantees.

00:18:02.273 --> 00:18:03.940 align:middle line:84%
So that's the end of
those four lessons,

00:18:03.940 --> 00:18:05.690 align:middle line:84%
and why I went
through those is going

00:18:05.690 --> 00:18:07.360 align:middle line:84%
to make sense in
about 20 seconds

00:18:07.360 --> 00:18:09.607 align:middle line:84%
because now we can start
talking about the next stage

00:18:09.607 --> 00:18:11.440 align:middle line:84%
in the history of
JavaScript, in the history

00:18:11.440 --> 00:18:17.110 align:middle line:84%
of programming in general, which
is the rapid rise of Metal.

00:18:17.110 --> 00:18:21.340 align:middle line:84%
As a motivation here, I have a
quote from a Microsoft research

00:18:21.340 --> 00:18:22.060 align:middle line:90%
paper--

00:18:22.060 --> 00:18:24.940 align:middle line:84%
"Hardware-based isolation incurs
nontrivial performance costs up

00:18:24.940 --> 00:18:28.588 align:middle line:84%
to 33%, and complicates
system implementation."

00:18:28.588 --> 00:18:30.130 align:middle line:84%
They're talking
about virtual memory,

00:18:30.130 --> 00:18:31.922 align:middle line:84%
and they're talking
about protection rings.

00:18:31.922 --> 00:18:34.060 align:middle line:84%
That's exactly what
they're talking about here.

00:18:34.060 --> 00:18:38.530 align:middle line:84%
The overhead for those things
is huge and often unrecognized

00:18:38.530 --> 00:18:43.430 align:middle line:84%
because most people don't deal
with that low-level system.

00:18:43.430 --> 00:18:46.240 align:middle line:84%
So what Metal is is a
recognition of this,

00:18:46.240 --> 00:18:49.120 align:middle line:84%
and it is a significant portion
of the Linux kernel with an ASM

00:18:49.120 --> 00:18:52.960 align:middle line:84%
VM embedded directly inside the
kernel and an implementation

00:18:52.960 --> 00:18:54.940 align:middle line:90%
of the DOM.

00:18:54.940 --> 00:18:57.490 align:middle line:90%
And we'll get to the DOM later.

00:18:57.490 --> 00:19:04.000 align:middle line:84%
But Metal is incapable
of running native code.

00:19:04.000 --> 00:19:05.920 align:middle line:84%
There is no such thing
as a native binary.

00:19:05.920 --> 00:19:08.230 align:middle line:84%
In fact, if you try to
run native x86 code,

00:19:08.230 --> 00:19:11.610 align:middle line:84%
or native any kind of
machine code in Metal,

00:19:11.610 --> 00:19:15.470 align:middle line:84%
it will transpile it into ASM,
chuck the ASM into the kernel,

00:19:15.470 --> 00:19:19.520 align:middle line:84%
and the kernel will JIT the
ASM back into native code.

00:19:19.520 --> 00:19:21.290 align:middle line:84%
And there's a very
good reason to do this.

00:19:21.290 --> 00:19:22.880 align:middle line:84%
I mean, that makes
native code fairly slow,

00:19:22.880 --> 00:19:25.005 align:middle line:84%
but most code is open-source,
so it doesn't matter.

00:19:25.005 --> 00:19:27.630 align:middle line:90%


00:19:27.630 --> 00:19:31.400 align:middle line:84%
The reason to do this
is that it saves you

00:19:31.400 --> 00:19:34.610 align:middle line:84%
from needing hardware
process isolation.

00:19:34.610 --> 00:19:37.330 align:middle line:84%
Because think about a
web browser, two tabs--

00:19:37.330 --> 00:19:38.630 align:middle line:90%
tab A, tab B--

00:19:38.630 --> 00:19:40.790 align:middle line:90%
both running JavaScript code.

00:19:40.790 --> 00:19:42.770 align:middle line:84%
You don't have any
fears that code in tab A

00:19:42.770 --> 00:19:45.268 align:middle line:84%
is going to overwrite
the variables of tab B,

00:19:45.268 --> 00:19:47.310 align:middle line:84%
and that's not because
the CPU's protecting you--

00:19:47.310 --> 00:19:48.720 align:middle line:84%
although, in some
browsers it is,

00:19:48.720 --> 00:19:51.000 align:middle line:84%
but many browsers
are single-process.

00:19:51.000 --> 00:19:53.360 align:middle line:84%
So the CPU's not doing
that, the VM is doing that.

00:19:53.360 --> 00:19:54.860 align:middle line:90%
It's already doing it.

00:19:54.860 --> 00:19:58.550 align:middle line:84%
And given that most code,
even in 2013, was running

00:19:58.550 --> 00:20:01.880 align:middle line:84%
through a VM, it's silly to
waste all that performance

00:20:01.880 --> 00:20:05.210 align:middle line:90%
on hardware isolation.

00:20:05.210 --> 00:20:08.060 align:middle line:84%
So the VM, the virtual
machine, inside the kernel

00:20:08.060 --> 00:20:11.180 align:middle line:84%
provides the protection that the
hardware, the memory management

00:20:11.180 --> 00:20:12.890 align:middle line:90%
unit, used to provide.

00:20:12.890 --> 00:20:16.070 align:middle line:84%
And it turns out that the loss
from going through that VM

00:20:16.070 --> 00:20:17.210 align:middle line:90%
is still about 20%.

00:20:17.210 --> 00:20:20.240 align:middle line:84%
Now, remember, upon the
initial release of ASM,

00:20:20.240 --> 00:20:23.775 align:middle line:84%
the loss was already 50%,
so we didn't actually

00:20:23.775 --> 00:20:24.650 align:middle line:90%
get that much faster.

00:20:24.650 --> 00:20:26.330 align:middle line:84%
And the reason is
there is some, sort

00:20:26.330 --> 00:20:29.030 align:middle line:84%
of, inherent complexity
there about protecting things

00:20:29.030 --> 00:20:31.460 align:middle line:84%
from each other, and there's
a little bit of just the fact

00:20:31.460 --> 00:20:34.460 align:middle line:84%
that this is a VM
in a kernel derived

00:20:34.460 --> 00:20:35.960 align:middle line:84%
from a language
designed in 10 days.

00:20:35.960 --> 00:20:39.140 align:middle line:90%
I mean, give it a break.

00:20:39.140 --> 00:20:40.700 align:middle line:90%
But we gain about 20%.

00:20:40.700 --> 00:20:43.880 align:middle line:84%
Now, that Microsoft research
paper estimated up to 33%.

00:20:43.880 --> 00:20:47.270 align:middle line:84%
Unsurprisingly, that
was overly ambitious,

00:20:47.270 --> 00:20:49.883 align:middle line:90%
but we gained about 20%.

00:20:49.883 --> 00:20:51.300 align:middle line:84%
Now, it looks like
this is a wash,

00:20:51.300 --> 00:20:54.260 align:middle line:84%
but if you remember how
multiplication works, 1.2

00:20:54.260 --> 00:20:58.700 align:middle line:84%
times 0.8 is not, in
fact, 1, it is 0.96.

00:20:58.700 --> 00:21:02.120 align:middle line:84%
So we have gained
4% performance.

00:21:02.120 --> 00:21:04.610 align:middle line:84%
We have shedded
4% of our runtime.

00:21:04.610 --> 00:21:09.320 align:middle line:84%
And if you took a 2010 piece
of hardware, a 2010 pile of C

00:21:09.320 --> 00:21:12.020 align:middle line:84%
code, and ran it
today through Metal,

00:21:12.020 --> 00:21:15.110 align:middle line:84%
it would run, on average, across
large suites of benchmarks,

00:21:15.110 --> 00:21:18.910 align:middle line:84%
4% faster than if you ran
it through, say, Linux.

00:21:18.910 --> 00:21:20.660 align:middle line:84%
And the reason for
that is the interaction

00:21:20.660 --> 00:21:27.800 align:middle line:84%
between the VM cost and the
hardware isolation savings.

00:21:27.800 --> 00:21:30.470 align:middle line:84%
Of course, if you're running
Python code or JavaScript

00:21:30.470 --> 00:21:33.230 align:middle line:84%
code for that matter, it's
just pure win for you.

00:21:33.230 --> 00:21:35.015 align:middle line:84%
You've saved the
hardware isolation cost,

00:21:35.015 --> 00:21:36.640 align:middle line:84%
and you were paying
the VM cost anyway.

00:21:36.640 --> 00:21:39.530 align:middle line:90%


00:21:39.530 --> 00:21:45.240 align:middle line:84%
This idea was hard to sell the
people in 2014 for two reasons.

00:21:45.240 --> 00:21:47.180 align:middle line:84%
First of all, most
programmers didn't really

00:21:47.180 --> 00:21:49.520 align:middle line:84%
understand these
low-level details

00:21:49.520 --> 00:21:51.660 align:middle line:84%
about how the MMU works,
how the CPU works,

00:21:51.660 --> 00:21:53.930 align:middle line:84%
how the kernel works, and
how all three work together

00:21:53.930 --> 00:21:55.730 align:middle line:90%
to provide isolation.

00:21:55.730 --> 00:21:59.540 align:middle line:84%
And second, because most
VMs were high-level--

00:21:59.540 --> 00:22:02.360 align:middle line:84%
things like the JVM, which,
despite being pretty fast,

00:22:02.360 --> 00:22:04.040 align:middle line:90%
is still a very high-level VM.

00:22:04.040 --> 00:22:08.238 align:middle line:84%
Or the CPython VM or
the YAR VM for Ruby.

00:22:08.238 --> 00:22:09.530 align:middle line:90%
These all were very high-level.

00:22:09.530 --> 00:22:12.960 align:middle line:84%
They were not designed to
compile closely to native code.

00:22:12.960 --> 00:22:17.677 align:middle line:84%
So our expectations were not
set up to appreciate this.

00:22:17.677 --> 00:22:19.760 align:middle line:84%
Of course, by doing this,
we gain a massive amount

00:22:19.760 --> 00:22:20.385 align:middle line:90%
of portability.

00:22:20.385 --> 00:22:22.340 align:middle line:84%
In fact, the problem
of CPU architecture

00:22:22.340 --> 00:22:24.740 align:middle line:84%
portability is
effectively dead today

00:22:24.740 --> 00:22:28.310 align:middle line:84%
for the 60% of programmers
who are programming on Metal,

00:22:28.310 --> 00:22:29.870 align:middle line:90%
because there is no native code.

00:22:29.870 --> 00:22:32.653 align:middle line:84%
And if there is no native code,
then there's nothing to port.

00:22:32.653 --> 00:22:34.070 align:middle line:84%
Of course, you
still have problems

00:22:34.070 --> 00:22:37.863 align:middle line:84%
like the C language has
several unspecified behaviors,

00:22:37.863 --> 00:22:39.530 align:middle line:84%
different compilers
do different things.

00:22:39.530 --> 00:22:41.540 align:middle line:84%
There's that kind of
portability still,

00:22:41.540 --> 00:22:45.070 align:middle line:84%
but there's not
CPU-level portability.

00:22:45.070 --> 00:22:47.570 align:middle line:84%
And what we're starting to see
as a result of that increased

00:22:47.570 --> 00:22:51.260 align:middle line:84%
portability is that people
are starting to store not only

00:22:51.260 --> 00:22:52.880 align:middle line:84%
their application
in version control,

00:22:52.880 --> 00:22:54.140 align:middle line:84%
but they're starting
to store things

00:22:54.140 --> 00:22:55.557 align:middle line:84%
like the database
or their queuing

00:22:55.557 --> 00:22:57.412 align:middle line:84%
server or whatever
components they need.

00:22:57.412 --> 00:22:59.120 align:middle line:84%
The entire source code
of them in version

00:22:59.120 --> 00:23:01.970 align:middle line:84%
control alongside the
compiled forms in ASM,

00:23:01.970 --> 00:23:04.370 align:middle line:90%
the equivalent of a binary.

00:23:04.370 --> 00:23:06.830 align:middle line:84%
And the reason to do this is
that if your entire system--

00:23:06.830 --> 00:23:09.050 align:middle line:84%
really, every single
dependency of your system--

00:23:09.050 --> 00:23:13.100 align:middle line:84%
is inversion control, then
a deploy is just push.

00:23:13.100 --> 00:23:14.660 align:middle line:84%
You push it to the
server, and you

00:23:14.660 --> 00:23:18.800 align:middle line:84%
kick the server over and let
it restart, and that's it.

00:23:18.800 --> 00:23:21.440 align:middle line:90%
There's no state there.

00:23:21.440 --> 00:23:25.340 align:middle line:84%
There's nothing like, oh, I
depend on this Python egg,

00:23:25.340 --> 00:23:27.770 align:middle line:84%
and it has to compile C
code, so now my server

00:23:27.770 --> 00:23:29.073 align:middle line:90%
needs a C compiler on it.

00:23:29.073 --> 00:23:30.740 align:middle line:84%
There's none of those
kinds of problems.

00:23:30.740 --> 00:23:33.510 align:middle line:90%


00:23:33.510 --> 00:23:35.790 align:middle line:84%
And, of course, at this
point, although JavaScript

00:23:35.790 --> 00:23:37.290 align:middle line:84%
has effectively
taken over the world

00:23:37.290 --> 00:23:40.320 align:middle line:84%
because 60% of programmers
are running all of their code

00:23:40.320 --> 00:23:43.860 align:middle line:84%
through ASM, the
language is dead.

00:23:43.860 --> 00:23:46.415 align:middle line:84%
In fact, I want to do
a very quick poll--

00:23:46.415 --> 00:23:48.540 align:middle line:84%
if you have written at
least one line of JavaScript

00:23:48.540 --> 00:23:51.180 align:middle line:84%
in the last year,
please raise your hand.

00:23:51.180 --> 00:23:53.613 align:middle line:84%
OK, so for the benefits
of any possible video,

00:23:53.613 --> 00:23:55.530 align:middle line:84%
there are several hundred
people in this room,

00:23:55.530 --> 00:23:57.600 align:middle line:84%
and there were maybe
five or so hands.

00:23:57.600 --> 00:24:02.790 align:middle line:90%
Because why would you do it?

00:24:02.790 --> 00:24:05.910 align:middle line:84%
I mean, this language
is quirky and flawed

00:24:05.910 --> 00:24:09.270 align:middle line:84%
in so many ways, and an enormous
success, sort of accidentally,

00:24:09.270 --> 00:24:13.410 align:middle line:84%
but why would you choose it over
all of the other languages that

00:24:13.410 --> 00:24:15.158 align:middle line:90%
now have compilers into ASM?

00:24:15.158 --> 00:24:16.950 align:middle line:84%
And, of course, there
are languages derived

00:24:16.950 --> 00:24:19.860 align:middle line:84%
from JavaScript that clean
up a lot of its mistakes,

00:24:19.860 --> 00:24:22.530 align:middle line:84%
and those are still in
use, but JavaScript itself

00:24:22.530 --> 00:24:25.050 align:middle line:90%
is effectively dead.

00:24:25.050 --> 00:24:26.370 align:middle line:90%
So we've now reached today.

00:24:26.370 --> 00:24:29.130 align:middle line:84%
As I mentioned, about
60% of programmers

00:24:29.130 --> 00:24:31.770 align:middle line:84%
are running their code
through Metal at this point.

00:24:31.770 --> 00:24:34.270 align:middle line:84%
The percentage for
non-programmers, of course,

00:24:34.270 --> 00:24:36.240 align:middle line:84%
is far smaller because
it is fundamentally

00:24:36.240 --> 00:24:38.400 align:middle line:90%
still a Unix underneath.

00:24:38.400 --> 00:24:40.140 align:middle line:84%
But now I want to
step back step back

00:24:40.140 --> 00:24:45.470 align:middle line:84%
and look at what has happened
in these 40 years as a whole.

00:24:45.470 --> 00:24:50.208 align:middle line:84%
The notion of binaries
is not dead in the sense

00:24:50.208 --> 00:24:52.500 align:middle line:84%
that no one's doing it, but
the writing is on the wall,

00:24:52.500 --> 00:24:57.240 align:middle line:84%
and it, very clearly, is
about to be properly dead.

00:24:57.240 --> 00:25:00.300 align:middle line:84%
The old C infrastructure
is effectively dead.

00:25:00.300 --> 00:25:03.990 align:middle line:84%
Things like the compiler, the
linker, the symbol stripper,

00:25:03.990 --> 00:25:07.440 align:middle line:84%
the debugger-- all of these very
old pieces of infrastructure

00:25:07.440 --> 00:25:11.010 align:middle line:84%
working on either native
code or object files--

00:25:11.010 --> 00:25:12.432 align:middle line:90%
is effectively dead.

00:25:12.432 --> 00:25:14.640 align:middle line:84%
I mean, ImageMagick is like
a cockroach-- it'll never

00:25:14.640 --> 00:25:18.660 align:middle line:84%
die-- but almost nothing
that we work on today

00:25:18.660 --> 00:25:22.110 align:middle line:84%
depends on this
old infrastructure.

00:25:22.110 --> 00:25:25.290 align:middle line:84%
Execution today of
code written in 2010

00:25:25.290 --> 00:25:29.670 align:middle line:84%
on hardware available in
2010 is slightly faster

00:25:29.670 --> 00:25:32.285 align:middle line:84%
than it would be with
2010 operating systems,

00:25:32.285 --> 00:25:33.660 align:middle line:84%
even though
everything is running

00:25:33.660 --> 00:25:36.660 align:middle line:84%
through this low-level
virtual machine.

00:25:36.660 --> 00:25:39.990 align:middle line:84%
And as mentioned, JavaScript,
once the most popular language

00:25:39.990 --> 00:25:41.610 align:middle line:84%
in the world, is
effectively dead.

00:25:41.610 --> 00:25:44.430 align:middle line:90%


00:25:44.430 --> 00:25:47.648 align:middle line:84%
It's important to note that
because I know that 40% of you,

00:25:47.648 --> 00:25:50.190 align:middle line:84%
statistically, are not running
all of your code through Metal

00:25:50.190 --> 00:25:51.050 align:middle line:90%
yet.

00:25:51.050 --> 00:25:52.980 align:middle line:84%
And some of you probably
have the objection

00:25:52.980 --> 00:25:57.600 align:middle line:84%
that I don't want my computer
to just be this web browser.

00:25:57.600 --> 00:26:01.650 align:middle line:84%
And Metal does not mean that
the web took over computers.

00:26:01.650 --> 00:26:04.225 align:middle line:84%
I mean, yes, JavaScript
is where ASM came from,

00:26:04.225 --> 00:26:05.850 align:middle line:84%
and JavaScript was
created for the web.

00:26:05.850 --> 00:26:09.870 align:middle line:84%
And yes, the DOM was something
that came from the web.

00:26:09.870 --> 00:26:14.640 align:middle line:84%
But the web is a linked
network of hypertext documents.

00:26:14.640 --> 00:26:16.473 align:middle line:84%
That is not what is
going on in your kernel.

00:26:16.473 --> 00:26:18.098 align:middle line:84%
Your kernel has a
programming language,

00:26:18.098 --> 00:26:19.740 align:middle line:84%
your kernel has a
rendering primitive.

00:26:19.740 --> 00:26:21.930 align:middle line:84%
And the fact that those
technologies originally

00:26:21.930 --> 00:26:25.920 align:middle line:84%
came from the web is not really
material to their usefulness

00:26:25.920 --> 00:26:27.630 align:middle line:90%
in a kernel.

00:26:27.630 --> 00:26:31.200 align:middle line:84%
And, of course, ASM is horribly
flawed in so many ways,

00:26:31.200 --> 00:26:34.140 align:middle line:84%
as is JavaScript,
but it is much better

00:26:34.140 --> 00:26:36.720 align:middle line:84%
than 15 competing CPU
architectures, which

00:26:36.720 --> 00:26:38.070 align:middle line:90%
is what we used to have.

00:26:38.070 --> 00:26:41.520 align:middle line:84%
And the DOM is flawed
in so many ways,

00:26:41.520 --> 00:26:43.590 align:middle line:84%
but it is much
better than having

00:26:43.590 --> 00:26:46.560 align:middle line:84%
Cocoa and Carbon and Win32
and eight other Windows

00:26:46.560 --> 00:26:52.710 align:middle line:84%
APIs and GTK and QT and all
of these competing windowing

00:26:52.710 --> 00:26:55.020 align:middle line:84%
systems that were sort of
treated like primitives,

00:26:55.020 --> 00:27:00.120 align:middle line:84%
and now they're all ultimately
rendering to the DOM.

00:27:00.120 --> 00:27:02.785 align:middle line:84%
And finally, for me,
the most important--

00:27:02.785 --> 00:27:04.410 align:middle line:84%
or not the most
important, but the most

00:27:04.410 --> 00:27:06.787 align:middle line:84%
interesting-- part of
this entire history

00:27:06.787 --> 00:27:09.120 align:middle line:84%
is that the JavaScript language
had to be a bad language

00:27:09.120 --> 00:27:12.180 align:middle line:84%
design, and it had to
be extremely popular

00:27:12.180 --> 00:27:13.760 align:middle line:90%
for us to get where we are.

00:27:13.760 --> 00:27:15.510 align:middle line:84%
And when I say it's a
bad language design,

00:27:15.510 --> 00:27:17.280 align:middle line:84%
I don't mean that Brendan
Eich is a bad designer,

00:27:17.280 --> 00:27:19.500 align:middle line:84%
I don't mean that Brendan
Eich is a stupid man.

00:27:19.500 --> 00:27:24.570 align:middle line:84%
He's a very intelligent man, but
he did it in 10 days in 1995--

00:27:24.570 --> 00:27:27.085 align:middle line:84%
there's only so far
that that can go.

00:27:27.085 --> 00:27:31.270 align:middle line:84%
And the reason it
had to be bad is

00:27:31.270 --> 00:27:34.680 align:middle line:84%
say that Rich Hickey
designed Clojure in 1995.

00:27:34.680 --> 00:27:36.533 align:middle line:90%
So carefully designed.

00:27:36.533 --> 00:27:38.950 align:middle line:84%
Yes, it's a Lisp, but once you
get passed the parentheses,

00:27:38.950 --> 00:27:41.040 align:middle line:90%
so, so, so nice.

00:27:41.040 --> 00:27:44.530 align:middle line:84%
And if that had been the
language in the browser,

00:27:44.530 --> 00:27:46.887 align:middle line:84%
it might have been good
enough for all of us

00:27:46.887 --> 00:27:48.720 align:middle line:84%
because once you get
passed the parentheses,

00:27:48.720 --> 00:27:52.830 align:middle line:90%
it is very, very nice language.

00:27:52.830 --> 00:27:55.033 align:middle line:84%
And JavaScript had to
be the only choice--

00:27:55.033 --> 00:27:56.700 align:middle line:84%
not just a bad choice,
but the only one.

00:27:56.700 --> 00:27:58.980 align:middle line:84%
Because if there were 10
choices in the browser, then

00:27:58.980 --> 00:28:00.660 align:middle line:84%
probably one of them would
have been good enough

00:28:00.660 --> 00:28:01.327 align:middle line:90%
for most people.

00:28:01.327 --> 00:28:03.510 align:middle line:84%
We would not have
felt this force on us

00:28:03.510 --> 00:28:07.030 align:middle line:84%
to escape from this one
choice that was not something

00:28:07.030 --> 00:28:11.070 align:middle line:84%
that most of us
wanted to program in.

00:28:11.070 --> 00:28:13.032 align:middle line:90%
So in the end, JavaScript lost.

00:28:13.032 --> 00:28:15.240 align:middle line:84%
It is effectively a dead
language for new development

00:28:15.240 --> 00:28:15.740 align:middle line:90%
now.

00:28:15.740 --> 00:28:17.340 align:middle line:84%
I mean, your bank
probably is running

00:28:17.340 --> 00:28:22.650 align:middle line:84%
a lot of JavaScript code, but
for the people in this room,

00:28:22.650 --> 00:28:24.210 align:middle line:84%
it is effectively
a dead language.

00:28:24.210 --> 00:28:27.702 align:middle line:84%
And as a result, programming
won, the act of programming.

00:28:27.702 --> 00:28:29.160 align:middle line:84%
And I know that
many of you weren't

00:28:29.160 --> 00:28:32.260 align:middle line:84%
around in 1995 or even
2005 as programmers,

00:28:32.260 --> 00:28:36.030 align:middle line:84%
so you remember this, but it
used to suck in a lot of ways.

00:28:36.030 --> 00:28:39.180 align:middle line:84%
And taking away the
portability problems

00:28:39.180 --> 00:28:41.850 align:middle line:84%
has been tremendously
beneficial.

00:28:41.850 --> 00:28:44.160 align:middle line:84%
And getting away from
all of that old compiling

00:28:44.160 --> 00:28:48.720 align:middle line:84%
infrastructure has
been very nice.

00:28:48.720 --> 00:28:50.490 align:middle line:90%
My name is Gary Bernhardt.

00:28:50.490 --> 00:28:52.023 align:middle line:84%
Back in the early-
to mid-teens, I

00:28:52.023 --> 00:28:53.940 align:middle line:84%
ran a company called
Destroy All Software that

00:28:53.940 --> 00:28:57.010 align:middle line:84%
published screencasts
on software development.

00:28:57.010 --> 00:28:59.110 align:middle line:84%
I haven't done anything
really of note since then,

00:28:59.110 --> 00:29:00.660 align:middle line:84%
so if you remember
me from anything,

00:29:00.660 --> 00:29:03.690 align:middle line:90%
it might be from that company.

00:29:03.690 --> 00:29:05.820 align:middle line:84%
And with that, I would
like to thank you

00:29:05.820 --> 00:29:08.100 align:middle line:84%
all very much for sitting
here for half an hour

00:29:08.100 --> 00:29:10.970 align:middle line:84%
and listening to me
speak so thank you.

00:29:10.970 --> 00:29:22.000 align:middle line:90%
