Compiled vs. Interpreted languages

Zach Dubno
3 min readJul 24, 2017

--

When we look at all of the different programming languages out there, we see that they are divided into two categories: compiled languages and interpreted languages.

To understand the difference between those, you must first start at the most basic levels of how a computer works. Distilled to its most basic state, any software of or program consists of the ones and zeros of binary, each representing an on or off value. A hard drive is a series of those ones and zeroes grouped into bytes and then kilobytes and so on. Unfortunately, humans don’t speak in base two so we needed some level of abstraction if we wanted to build anything efficiently. Thus Assembly and Assembler were born. Assembly is a text based programming language, where almost every word has a direct cognate in machine code (binary). Unlike binary, however, a CPU (Central Processing Unit) cannot understand it. That’s where Assembler comes in: Assembler is the compiler for Assembly.

What Assembler, and any other compiler, does is it translates the keywords and symbols that we use into binary that the computer can understand. According to Wikipedia, “A compiler is computer software that transforms computer code written in one programming language (the source language) into another computer language (the target language).”

Gradually languages got more and more abstract from their machine code correspondents, and compilers became more complex to support them. Although we could now write comprehensive code in a way that makes sense to programmers, there are several significant drawbacks to compiled languages that lead to the development of interpreters and interpreted languages.

  • Good compilers are extremely hard to write; interpreted languages are much easier to implement
  • You have to wait for code to compile before you run it, making it much harder to test and write on the fly
relevent XKCD
  • very hard to test because all of the code is compiled first and then run; interpreted languages let you figure out what’s broken much more easily

Due to all of these, a brilliant creation was born: interpreters. Interpreters initially ran through your code line by line and translated each line into a sequence of subroutines already compiled into machine code. This had a huge drawback though: looping and iteration caused certain lines to be compiled over and over again. This was inefficient and caused code to run slower.

Many languages that are defined as interpreted, including Ruby, actually use a combination of compiling and interpreting, called intermediate representation. Intermediate representation is when an interpreter runs through code multiple times, first transforming code into a graph structure and then converting it into actual machine code. This graph structure allows things like re-arrangement, such as how ruby hoists variable declarations, and flow analysis. Flow analysis is when the computer figures out values to assign variables interspersed through the program.

Having the computer break apart the code and then run each line has many advantages, such as:

  • dynamic scoping of variables and declarations
  • platform independence
  • much better testing and errors

despite these advantages, there are some disadvantages to interpreted languages:

  • much slower execution, due to a programming having to be gone through multiple times for each run
  • sometimes hackers can inject code into interpreters to change the course of execution
  • code can be copied of reverse engineered much more easily by competitors
  • can be less reliable

Each type of language has many pros and cons, and there are many languages that use a combination of the two. Keep in mind, however, that you can do anything that you would do in a compiled language in an interpreted one, and anything you would in an interpreted language in a compiled one.

--

--