Hero Code Examples for Programming Languages: Revisiting Trabb-Pardo_Knuth

“The best way to grasp the spirit of a programming language is to read example programs” as Knuth wrote in the “The Early Development of Programming Languages” 1. Today, it is common practice to provide an example program on the front page of a programming language’s marketing site (i.e., a “hero code example” as it were). Since the objective of the example is to showcase the language’s value versus others, what coding tasks best fulfill that? Beyond Hello World, which is the most popular example coding task, there is little agreement between sites. I survey existing practice, discuss the utility of the Trabb-Pardo Knuth algorithm, and make recommendations on tasks that can demonstrate value versus the “next best alternative”.

Showing a complete example program at the beginning of a language’s documentation has a long, but not universal, tradition. The 1956 FORTRAN Programmer’s Reference Manual illustrated the new language with an example of finding the maximum element in an array on the very first page of chapter 1. The 1964 Dartmouth BASIC Manual demonstrating solving two simultaneous linear equations on page 3. Iverson’s 1962 A Programming Language computes the area of a circle on page 2. However, the 1962 COBOL specification did not include a full program anywhere in the document and the LISP I Programmer’s Manual took 23 pages until you saw something close to a full example of a program.

Survey of Current Practice

Based on 33 websites for general purpose languages that featured at least one coding example on the landing page (pulling from posts to Lobste.rs and HN where a language was advertised), I recorded 71 tasks across 91 code examples. The most popular tasks and their rough Rosetta Code equivalents are:

  1. “Hello World” with 7 examples Hello World/Text
  2. Examples of defining a data class/record/class with 5 examples Classes Compound Data Type
  3. “Hello World” variants (e.g. cases where the example demonstrated string concatenation or other additional computation prior to displaying the message) with 4 examples
  4. “Hello World” provided via a web call with 3 examples Hello World/Web Server
  5. Fibonacci with 3 examples Fibonacci Sequence

There were 2 examples of straight-forward equations/math computations, array processing, counting the number of occurrences of a value in a list, and computing factorials. All other tasks had a singular example. Some tasks were about the ecosystem rather than the language and demonstrated features such as unit tests, dependency management, or builds.

I only encountered one instance where a site solely used Hello World, versus as one example of many.

Limitations of Hello World for Modern Languages

Hello World as the introductory code example was popularized by K&R’s The C Programming Language (with the first Hello World appearing (obliquely) in a B language tutorial). In K&R’s second edition, the virtues of Hello World are described thus:

This is the big hurdle; to leap over it you have to be able to create the program text somewhere, compile it successfully, load it, run it, and find out where your output went. With these mechanical details mastered, everything else is comparatively easy.

Hello World has a didactic purpose in demonstrating that the infrastructure works.2 When this was written in 1978, these mechanical details were particularly difficult, but there is a reason most programmers are given a day to setup a new computer given how many things need to be downloaded and configured before they are productive.

However, Hello World demonstrates very little about the programming language itself. The example shows a minimal skeleton of a program, how to import a module (if I/O is provided via a module), and a minimal example of formatted I/O (i.e. the newline) and strings. Given that a language designer needs to differentiate their language, this example provides little opportunity to do so.

To demonstrate, here are over 300 examples drawn from Rosetta Code for Hello World. This list limits the examples to those which take a single line. I imagine your eyes will glaze over with how many languages are so close to print "Hello, World!" (you may need to open the image in a new tab).

Three columns of Hello World programs from Rosetta Code
Single Line Hello World Examples

So, what alternative tasks may be useful?

Trabb-Pardo-Knuth (TPK) Algorithm

The Trabb-Pardo Knuth (TPK) algorithm is a coding task used to illustrate and compare early programming languages. The historical survey 1 coverered languages from Zuse’s Plancalculus (1945) to IAL in 1958, and included an example implementation (as far as possible) in twenty languages. TPK is an artificial task designed to demonstrate multiple aspects of a programming language. The definition of the task is given by the ALGOL60 program:

TPK: begin integer i; real y; real array a[0:10];
	real procedure f(t); real t; value t;
		f := sqrt(abs(t)) + 5 x t🠕3;
	for i := 0 step 1 until 10 do read(a[i]);
	for i := 10 step -1 until 0 do
		begin y := f(a[i]);
			if y > 400 then write(i, 'TOO LARGE')
					   else write(i, y);
		end
	end TPK.

In English, the task is to read 11 numbers, compute f() for each, and in reverse order, print the index and f() result unless f() is over 400, in which case print ‘TOO LARGE’.

The Computer History Museum has a lecture from Donald Knuth – A Dozen Precursors of Fortran that discusses the TPK algorithm and early programming languages. The TPK discussion starts at 10:50.

TPK illustrates:

  1. Function definition and invocation
  2. Mathematical expressions (involving precedence and operations beyond arithmetic)
  3. Data types (not all languages supported data types, so this was a ‘best effort’ requirement)
  4. Loops/iteration
  5. Conditionals
  6. I/O (not all languages supported I/O, so this was a ‘best effort’ requirement)
  7. Program structure (e.g. program entry point)

In the lecture, Knuth states the objective of the task was “a short program that does nothing important, but […] almost everything that a language has to do in general”.

Advantages and Limitations of TPK for Modern Languages

The task definition is sufficiently vague that an implementer can fit in additional language features. For example, the test and handling for the overflow condition can be converted into an Optional type. Explicit for-loops and indexing can be replaced by iterators and more functional-style streaming operations.

A major focus in the survey is the computation. In the survey, many of the languages had … involved… syntax for mathematical expressions. Parsing a general expression was a difficult problem because 1) most parsing theory hadn’t been discovered yet and 2) hardware limits. However, the international effort in the late 50s towards languages that supported algebraic expressions was successful. Today, Lisp and Forth descended languages may still have prefix and postfix notation, but infix has won. Math functions may be hidden within a module and exponentiation may be either a library function or built-in to the language, but math expressions in languages look very similar.

In the spirit of “everything that a language has to do”, in comparison to typical modern programming tasks, the task does not require a compound data type nor lends itself to any sort of object. The task does not require error handling and would not benefit from concurrency (although both could be added to the example).

Recommendation

Since Hello World has didactic value rather than marketing value, it is best placed in the tutorial/documentation portion of the website, rather than on the front-page.

TPK, while an artificial task, demonstrates a large number of language features succinctly and different implementations can be compared easily.

Since TPK does not involve any compound data types or data modeling, a good secondary task is modeling Complex numbers or Quaternions, which can showcase object-oriented features and definition of new operators. Since both are still very mathematical, an alternative like Search a List of Records includes strings and numbers, data structures and (potentially) compound types, as well as the ability to showcase higher-order functions.

I suspect that any example for concurrency will need to be tailored to the specific concurrency models implemented, as well as differences between support via language versus libraries. Given how many sites use concurrency in an example (and its relevance to SaaS developers), there is evident marketing value in showing those features, but the use cases are very divergent.

References


  1. Donald E. Knuth, Luis Trabb Pardo. “The Early Development of Programming Languages.” Encyclopedia of Computer Science and Technology, edited by J. Belzer, A. G. Holzman, and A. Kent, Dekker, 1977, Vol. 6, pp. 419–493. doi archive/DTIC website collected papers isbn search ↩︎

  2. This purpose was lost on the critics who complained the example failed to demonstrate object-oriented programming. See Technical opinion: Hello, world considered harmful and the works that cite it. ↩︎