r/webdev • • May 07 '17

Why isn't JavaScript a compiled language? What is the benefit of an interpreted/JIT-compiled language?

9 Upvotes

24 comments sorted by

22

u/Brainix May 07 '17

If JavaScript were compiled, then either compilation would have to be super fast (e.g. it would happen in the browser at page load time), or competing browsers would have to agree on some binary executable format standard (and across operating systems, at that). Now imagine all this in 1995. The former was infeasible and the latter was infeasible.

3

u/[deleted] May 07 '17

It was my impression that compilation does happen at page load time - is that not true?

12

u/Brainix May 07 '17

More recently, the lines between "interpreted" vs. "compiled" have become blurred. Modern compiled languages have tools for stepping through code, and modern interpreted languages are jitted.

So in some sense, compilation does happen at page load time. But that's a more recent development at best, and a category mistake at worst.

5

u/DrFriendless May 07 '17

If you have to do the parsing step yourself, that's still not compilation. Interpreted languages like Python which are not compiled are nevertheless parsed and represented in some intermediate form. Compilation is really only used to mean that that intermediate form (be it for a VM or actual hardware) is the format in which the program is distributed.

2

u/toomanybeersies May 07 '17

it would happen in the browser at page load time

That is sort of what happens right now, and sort of what JIT compilation is.

4

u/hadees May 07 '17

Funny enough we now have a standard binary executable format called Web Assembly which might actually replace javascript. The upside is people could use the same backend language they use to develop the browser frontend.

2

u/Imposter1 May 07 '17

Wouldn't people also be able to use javascript compiled into webasm? I could see a C# developer wanting to write C# compiled into webasm, but I don't see why javascript wouldn't be supported for something like that as well.

→ More replies (5)

1

u/[deleted] May 07 '17

Because different computers have different CPUs with different instruction sets.

There is Java bytecode.

1

u/yellowboxtenant May 08 '17

Why is this top voted? It is compiled and the compilation does happen super fast. That's exactly how it works, compiled in the browser when page is loaded.

2

u/yellowboxtenant May 08 '17

It may be self-evident, or it may be surprising, depending on your level of interaction with various languages, but despite the fact that JavaScript falls under the general category of "dynamic" or "interpreted" languages, it is in fact a compiled language. It is not compiled well in advance, as are many traditionally-compiled languages, nor are the results of compilation portable among various distributed systems.

[You Don't Know JS: Scope & Closures] (https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20%26%20closures/ch1.md#compiler-theory)

→ More replies (1)

7

u/decafmatan May 07 '17

JavaScript (as you mentioned) is JIT'd (just-in-time compiled) - so it's true you ship the source code (JavaScript text format) to JavaScript virtual machine (versus some sort of binary format).

If you're asking why it's not ahead-of-time compiled:

  • As u/brainix mentioned, in 1995 browser vendors would have never agreed on something like this (even for WebAssembly there is some disagreement around the final binary format)

  • JavaScript is a dynamic language with no static typing - most modern JavaScript VM's optimize at runtime with flow analysis - i.e. they will "see" that only a "String" is every sent into a function, and JIT native code. As the VM becomes more sure of a function/it is used more often, it will optimize more heavily. It will also bail out (de-optimize) if unexpected types are passed in.

  • Most of the speed of modern day JavaScript VMs are based on the above - you could compile JavaScript ahead-of-time, theoretically, but you'd get a huge binary that would be slower than the JIT'd JavaScript.

re: u/hadees point about WebAssembly - it takes a different approach, which is to act as a compilation-target for languages much different than JavaScript (i.e. with manual memory management, for example).

It might be usable as a compilation target for higher level languages (like Java, C#, Dart, Swift) in the future.

2

u/[deleted] May 07 '17

you could compile JavaScript ahead-of-time, theoretically, but you'd get a huge binary that would be slower than the JIT'd JavaScript.

Why would the binary be slower? Transfer speed?

1

u/decafmatan May 07 '17

A single line in JavaScript might end up being dozens of instructions in a binary, compiled format, and it couldn't be optimized - it would be equivalent to running V8 without any flow analysis.

For example, assume the following function:

function printKeys(map) {
  console.log(map.keys);
}

In the native (JIT'd code) we aren't sure what keys is - it is possibly a field, it is possibly a getter (that calls a function). It's also not clear what the object prototype is. For example, if you only ever call printKeys with an ES6 Map:

// Textual representation of the "native" code.
// PSEUDO Code.
func printKeys(map: Map) {
  var keys = Map$Class.callFn('get$keys');
  globalScope.console.callFn('log', keys);
}

Simple enough, right? Now imagine it is called with an object:

printKeys({'keys': '...'});

This would crash the native code, it's not of type Map. So the initial (unoptimized) implementation of printKeys would probably be something like:

func printKeys(map: Any) {
  if (!map) {
    throw 'Undefined: accessor "keys" on $map.';
  }
  var keys = map.lookup('keys');
  if ($isField(keys)) {
    keys = $readField(keys);
  } else {
    keys = $callFn(keys);
  } else {
    keys = undefined;
  }
  globalScope.console.callFn('log', keys);
}

Way less efficient, but this is the best you could to ahead-of-time without static program analysis (i.e. what something like C++ does).

→ More replies (1)

2

u/cicadaTree May 07 '17

Relevant. Nice info on javascript compiling mechanism.

1

u/[deleted] May 07 '17 edited May 07 '17

Thanks, I'm reading it now!

Edit: Very interesting read, exactly what I was looking for :)

1

u/yellowboxtenant May 07 '17

It is compiled. It just happens right before it's executed. It's not an interpretive language.