Philip Guo (Phil Guo, Philip J. Guo, Philip Jia Guo, pgbovine)

What is a programming language? A six-layer model

(15-minute talk)
Summary
To me, a programming language consists of six layers: specification, implementation, run-time environment, standard library, third-party libraries, and community. I'll use the JavaScript language to illustrate these layers.

This article is adapted from a 15-minute talk I gave at the University of Rochester's annual hackathon in April 2016:

To watch a longer lecture on this topic, see What is a programming language? (45-minute lecture)


What is a programming language?

When someone says that a language is good or bad, useful or impractical, elegant or messy, what are they referring to?

I want to walk through what a programming language means to me. To me, a programming language consists of six layers:

  1. Specification
  2. Implementation
  3. Run-time environment
  4. Standard library
  5. Third-party libraries
  6. Community

Imagine a burrito with six layers, with specification as the base layer of beans and community as the outer tortilla wrapping.

Let's use the JavaScript language to illustrate these layers.

Layer 1: Specification

At its core, a programming language is simply a document called a specification that people wrote and agreed upon. Here is the specification for the 2015 edition of JavaScript (called ECMAScript for boring historical reasons). The PDF version is 566 pages. Enthralling reading, huh?

A specification describes both the syntax and semantics of a programming language. If someone gives you a piece of code, you can, in theory, refer to the language's specification to determine exactly what that code is supposed to do. But that process would be unbearably slow, so that's why we have ...

Layer 2: Implementation

A specification is useless without an implementation, which is a computer program that takes as input a piece of code in your language and produces as output what the specification says that code should do. For instance, a JavaScript implementation (sometimes called a JavaScript engine) takes your JavaScript code as input, runs that code, and produces as output what the specification says that code should do. Without a computer-based implementation, you need humans to manually “run” that code.

Engineers spend bazillions of hours creating implementations that run code as fast as possible. You might have heard the terms interpreter, compiler, or just-in-time compiler. Those are techniques for creating implementations, which usually trade off simplicity for speed.

As of 2016, the most popular JavaScript implementations are all just-in-time compilers created by organizations that make the most popular web browsers (more on that in the next section):

(What language is a JavaScript implementation written in? Good question to ponder!)

Layer 3: Run-time environment

An implementation runs your code on some device (e.g., a computer, mobile phone, or smartwatch), but is that enough to do something useful? If I gave you a JavaScript implementation by itself, it still doesn't do much for you beyond running “Hello World” programs of the sort that you write in introductory classes. For a language to be truly useful, its implementation must be situated within a compelling run-time environment.

By far the most compelling run-time environment for JavaScript is a web browser like the one you're using to read this article. JavaScript code running within your web browser is responsible for all of the dynamic content (and annoying ads) on web pages. Without JavaScript, the web would still be a collection of static documents instead of a rich platform for computation.

Unsurprisingly, the most popular JavaScript implementations from the prior section each run within a popular web browser:

Although JavaScript is commonly run within a web browser, people have also used it in other run-time environments such as web servers (e.g., Node.js) and traditional Windows, Mac, and Linux desktop applications (e.g., Electron).

Layer 4: Standard library

Each run-time environment comes with a standard library of functions and objects that perform useful tasks such as manipulating text strings, parsing dates, and doing advanced math. Here is a JavaScript standard library from Mozilla.

Unfortunately, JavaScript is not known for having a great standard library, so people have been forced to fill in the gaps with a cornucopia of third-party libraries (see next section).

In contrast, a language such as Python is known for having a well-designed and feature-rich standard library so that many practical programs can be written without installing third-party libraries.

Layer 5: Third-party libraries

A standard library can't practically handle all of the common tasks that programmers may want to do in a language. Thus, to make a language more widely useful, programmers package up collections of their own code into third-party libraries that anyone can download and incorporate into their projects. Popular libraries for JavaScript include Underscore, jQuery, and D3.

A language's success often depends on how many third-party libraries are available and how well they are curated. To better organize these libraries, people invented tools called package managers. The most popular package manager for JavaScript is npm, which now contains over 260,000 open-source libraries. Due to the momentum of npm, JavaScript currently has the greatest number of third-party libraries of any language.

Who writes these libraries? This question brings us to the final layer ...

Layer 6: Community

The outermost layer (burrito wrapping) of a programming language is the community of programmers who write code in that language.

One aspect of community consists of professional conferences where people share experience stories, new ideas, and tech demos. For JavaScript, the JSConf organization manages a series of popular conferences. Another aspect involves online communities such as help forums and technical blogs.

Since programming languages are ultimately written by and for people, a language succeeds or fails based on the people who use it. Is your community vibrant and inclusive? Or stagnant and off-putting? Are people helpful and encouraging to beginners? Or scary and intimidating? Both in-person and online communities shape people's impressions of a language and are vital for that language's long-term sustainability.

In sum, if you want to create a new language from scratch and see it get adopted in the real world, then you need to take all six layers into account. Simply writing a mathematically-elegant specification or a lightning-fast implementation isn't enough. Think about the people. Think about the entire burrito. Happy hacking!

Created: 2016-03-28
Last modified: 2016-03-28
Related pages tagged as programming: