Appeared in:
Influenced by:
Typing discipline:
Versions and implementations (Collapse all | Expand all):
Programming language

CPL (from Combined/Cambridge Programming Language) — programming language developed in a joint effort of Cambridge and London Universities in 1960s. Sometimes the name is jokingly decoded as Cambridge Plus London.

The article “The Main Features of CPL” was published in 1963; it described the main features of the language, but it had no implementation yet. The language was mainly influenced by Algol60, but attempted to extend its usage to other application areas, mainly the research in programming and compilers development, and thus it became cumbersome.

Due to the language size and complexity the first working compiler appeared only in 1970. It was meant for usage on two similar machines — Atlas in London and Titan in Cambridge. CPL never became popular and disappeared in mid-1970s, but not before it influenced the creation of BCPL.

A CPL program consists of definitions and commands. A definition is an association of a certain name with a certain data unit, data structure, function or a process description. There are two types of names in the language — small (a single lowercase letter, possibly followed by several primes) and large (an uppercase letter, followed by more letters, digits and primes). In contrast, reserved words are written underlined (if written by hand) or in bold font (in print). A command is an instruction to perform certain evaluation or to rearrange information stored.

Both definitions and commands are built from expressions; CPL allows to build complex expressions from a small basic set of forms.

Programs are arranged in sections (“blocks”). In the basic case a block contains a set of definitions (all definitions are activated simultaneously), followed by a sequence of commands (the commands are executed one by one, sequentially or in the order defined by flow control commands). Blocks can be nested.

CPL has a rich set of basic data types: numerical (index, integer, real and complex), logical, label, string and two data structures — array and list. More complicated data structures can be built by combining basic types.

Main features of the language:

  • a rich set of flow control structures, including a variety of loops (most of them inherited by BCPL).
  • means of creating and calling user-defined functions and procedures (routine). Functions have no side effects, and can return a value of type “function”. Procedures can be passed as parameters to other procedures (but not functions!). Thus, CPL implements the basic elements of functional programming.
  • several ways to define a complex expression and get its result. Here go: where clause which allows to define a local expression-scoped variable; result of clause which allows to use a block as an expression; conditional expressions b→e1,e2 which return different expressions depending on the value of the logical variable; and simultaneous assignment commands.
  • stream-based IO routines. A program can use several streams of each type; commands Input and Output allow to set the index of the stream used next, and Source and Destination query the index of the current stream.

Elements of syntax:

Case-sensitivity yes
Variable assignment <varname> := <value>
Variable declaration <type> <varname>
Variable declaration with assignment <type> <varname> = <value>
Grouping expressions § ... §
Block § ... §
Physical (shallow) equality =
Physical (shallow) inequality
Comparison < > ≤ ≥
If - then if <condition> then do <trueBlock>
If - then - else test <condition> then do <trueBlock> or do <falseBlock>
While condition do while <condition> do <loopBody> / until <condition> do <loopBody>
Do until condition <loopBody> repeat while <condition> / <loopBody> repeat until <condition>
For each value in a numeric range, 1 increment for i = step 1, 1, 10 do <loopBody>


Hello, World!:

Example for versions CPL

Generally Write outputs a list of elements, but in this case it prints a string literal.

Write("Hello, World!")


Example for versions CPL

(Example from language description) This is a recursive factorial definition (note the rec modifier which stresses this). To implement different processing scenarios for different values of x, a conditional expression is used instead of if.

rec function Fact1[x] = (x = 0)  1, xFact1[x  1]


Example for versions CPL

(Example from language description) This code shows an iterative way to calculate factorial.

result of clause allows to use a block as an expression. The body of the block must contain an assignment to variable result. The block may contain local variables, but nothing which could result in a side effect (for example, changing the values of external variables is prohibited). This clause is typically used with function definitions.

Loop body uses simultaneous assignment of new values to the variables. Both of them use small names, so the language allows to skip multiplication sign between them — xf is treated same as x*f.

function Fact2[x] = result of
    § real f = 1
      until x = 0 do
          f, x := xf, x  1
      result : = f §