What's the difference between compilers and interpreters?

Last Update: 2023-04-22

This blog post will explain what compilers are and what interpreters are. Then the differences are outlined and why there's a blurry line between them.

For more information about some of the terms used here, go to my compiler and interpreter lexicon.

What's a compiler?

A compiler transforms code into a different or even the same kind of code. Typically, compilers are defined by transforming human-readable source code into machine readable code.

Examples for compilers are GCC, clang, javac or the TypeScript compiler. Even a JavaScript minifier could be defined as a compiler.

I personally would define something as a compiler, if it has deeper knowledge about the input code and the output is a different kind of code, that semantically does the same thing.

What's an interpreter?

An interpreter executes code immediatly. Technically, a virtual machine executing bytecode could also be counted as an interpreter. Though, typically the input is expected to be high-level, human-readable code.

Examples for interpreters are V8, CPython or technically the JVM.

So what's the difference?

The typically definition is that a compiler transforms code into machine code, that will be executed later, and interpreters execute code immediatly.

A compiler doesn't execute code, that mutates the runtime or the system, an interpreter does.

And why is that so hard to define today?

Interpreters like V8 can compile the code into bytecode or machine code, so that the execution of the code is faster (this is called JIT compilation). See How JavaScript works: Optimizing the V8 compiler for efficiency for more information.

Likewise, compilers can execute code at runtime see constexpr in C++.

Rust (or Cargo for that matter) can even execute not-constant-code at compile time, see Build Scripts or proc_macro.