Five Languages

@rosettacode: Pick three to five programming languages for teaching orthogonal programming paradigms. Which did you choose? Why? Blog and I'll share.

Interesting you should ask that, Rosetta Code. I’ve been pondering similar questions before, most recently inspired by Bruce Tate’s Seven Languages in Seven Weeks, whose languages of choice were sometimes overlapping (e.g. Io and Ruby) while leaving certain areas, such as concatenative languages, unexplored. What languages would I have chosen?

Let’s start with the paradigms. It’s not a very clear term; is object orientation a paradigm, or just a technique that can be applied to programs written in both imperative and declarative style? Is imperative programming a paradigm? If so, what is procedural programming? The orthogonality requirement complicates things further. Functional programming is not orthogonal to procedural programming, but OO is to both, so how do we choose which features to represent? We are going to just gloss over these formal problems and arbitrarily select five diverse families of programming languages:

  • imperative
  • functional
  • object-oriented
  • logic
  • Lisp-like

and then try to cover as many different features within each family, as practical.

What languages should represent them? Given the limit of five, it might seem that multi-paradigm ones suche as C++, Oz or Scala would offer the biggest bang for the buck. However, considering that the purpose is teaching, we will be better off with smaller languages; ideas can be better appreciated and internalised when presented in a context of a language that was specifically designed around them. As a result our criteria for choice will be:

  • small – both conceptually and syntactically: can be learned faster
  • “there is only one way”: a paradigm or feature is represented clearly, preferably in its pure form
  • representative: contain constructs that are commonly found in other languages representing the same paradigm
  • practical: the language is used in the “real world”, there exists a community, tutorials, libraries and other resources
  • influential: other languages have been designed after features introduced first in this language

Imperative

The way contemparary computers work is inherently imperative: code is simply a list of instructions for the CPU. It therefore is fitting to pick for the representative of imperative family a language that makes this connection tangible – a low-level, systems programming language such as C. C is perhaps better known for its obfuscability than for the didactic virtues, but appears to match our criteria fairly well: it is relatively small, doesn’t support any other style than imperative, has a huge codebase written in it and its syntax influenced most of today’s mainstream languages. Students learning C will be exposed to:

  • control flow instructions
  • manual memory management
  • pointers and pointer arithmetic
  • undefined behaviour

Contenders: Assembly, Pascal, Python

Functional

Since we aim for paradigmatic purity and try to avoid obscurity, Haskell – a purely functional language with a large, active community is a natural choice. Syntactic sugar notwithstanding, the core is very small and can be boiled down to lambda abstraction and function application. It provides excellent platform to explain concepts such as

  • lambda calculus
  • laziness
  • strong typing
  • type inference
  • side-effect isolation
  • tail call optimisation
  • REPL

Contenders: StandardML, OCaml, also Scheme and Clojure, if we didn’t have a separate category for them

Object-oriented

There are two main flavours of object orientation: object-based and class-based. While the former requires fewer concepts to explain, the latter is much more common in the industry and has an excellent, dogmatic representative: Smalltalk. In Smalltalk everything is an object, even conditional instructions are in fact messages sent to Boolean objects. Exactly the conceptual minimalism we have been looking for, at the same time introducing new features such as:

  • objects responding to messages
  • class inheritance
  • dynamic typing
  • image-based development environment

Contenders: Python, Io, Eiffel, Ruby

Logic

Logic programming’s heyday seems to have passed with the 1970s and 80s, but certains concepts are very relevant today. Want to understand how generic Scala collection methods return the most specific type in a given context? Lear about Horn clauses and unification! Prolog is by far the most popular language in this paradigm, so we don’t really have much choice if we want a language built around

  • logic programming
  • term unification

Contenders: none

Lisp-like

Lisp-likeness is not a paradigm by a long shot; Lisp is usually considered a functional language, and we have already covered that paradigm. The temptation to instead include a concatenative language was high, but the historical importance and influence of Forth pales in comparison with Lisp. Lisp, with its homoiconicity, flexible (some say non-existent) syntax and macro system is a platform of choice for many programming language researchers for a reason. From the countless dialects that mushroomed over the years we will pick Clojure, which, beside being a modern language with strong and growing community, will also expose our students to one of the major contemporary runtimes – the Java Virtual Machine. So, here’s what they can learn about:

  • abstract syntax trees
  • macros
  • homoiconicity
  • lambda calculus
  • dynamic typing
  • continuations
  • REPL
  • JVM

Contenders: Scheme, Emacs Lisp, also Factor and Forth – if we went for concatenative instead.

What is missing?

A lot, obviously, especially in the more exotic end of paradigm spectrum, such as concatenative or array-based languages. It would have been nice to include at least one language with advanced module system (e.g. Standard ML) to demonstrate features that help build programs in-the-large. That said, we managed to cover an impressive list of concepts and someone who learns these five languages in reasonable depth can definitely be called a programming erudite.