Following on from this popular question about K&R-style argument specification, in which we discussed the history of routines with formal argument lists not including type information (i.e., as in K&R C), I'd like to ask when the more modern form of having type information in the argument list appeared. This is basically a 'first' type question, but I think it's something we can pin down reasonably well.

An answer to the previous question mentioned that such a style was seen in Algol 68, but that was not the first such.

Some definitions and constraints:

  • I'm asking about languages which have the concept of typed variables
  • The language must permit the declaration of variables with a specific type
  • The language need not necessarily require the declaration of all variables - i.e., FORTRAN-style defaults are allowed
  • The language must have routine declarations of some kind, that include a list of formal (or 'dummy') arguments
  • The language must permit the types of the formal arguments to be specified
  • The language need not necessarily require the specification of all argument types

The question is specifically asking for a language in which the type information for the formal arguments, if explicit, is included in the argument list itself, and not as separate statements or clauses. If the language distinguishes 'functions' and 'subroutines', either of the two will suffice.

  • 3
    Doesn't it kind of come down to the point when languages added explicit typing, like in case of ALGOL as Algol68 vs. Algol60?
    – Raffzahn
    Commented Feb 6, 2022 at 23:44
  • I've always thought the first was Algol 68.
    – texdr.aft
    Commented Feb 7, 2022 at 0:06
  • 2
    @Raffzahn - I don't see it that way. In the case of Algol 60, the language did not require explicit specification of argument types, but many implementations did. CPL (my answer) allows but does not require argument typing, but when you do provide types, they're in the argument list.
    – dave
    Commented Feb 7, 2022 at 1:41
  • @texdr.aft - until recently, I'd have thought so too!
    – dave
    Commented Feb 7, 2022 at 1:44
  • @another-dave Erm, somehow you lost me. Ar you saying Algol 68 does not use (optional) typing?
    – Raffzahn
    Commented Feb 7, 2022 at 2:00

2 Answers 2


CPL (Cambridge/Combined Programming Language, Christopher's Programming Language), though apparently never completely implemented in its heyday, went most of the way towards current practice. I therefore credit it with introducing 'type' into the formal argument list.

CPL was intended to improve upon Algol 60; whereas Algol 60 was intended for essentially numerical computations, CPL was designed as a language for building systems (in particular, the OS for the new Titan computer at Cambridge).

This answer is based on the description of CPL in the 1963 paper, The Main Features of CPL, by Barron et. al. Regardless of when, or indeed if, it was implemented, the published paper surely put the idea out there for other language designers.

In Algol 60, a procedure looked like:

procedure work(a, b, c, d, e);
value a; real a, b, c; int d; label e;

The (optional) 'specification' part gave the types of the identifiers, and also the mechanism that was to be used ('by value' or 'by name', the latter being the default).

In CPL, this became:

routine Work [real a, b, c, index d, label e]
value a, e; ref c; subst b, d

The type specifications have been absorbed into the argument list in the modern style. Mechanisms are still specified separately, not yet having been combined with type. subst is the CPL term for call-by-name; ref has essentially its modern meaning, but is not part of the type.

Note that real does not have to be repeated for each argument; the rule is that in the absence of a type, it's the same as the previous argument (with the first being implicitly real if not explicitly typed).

By the time of Algol 68, value would become unnecessary (an argument of type real is passed by value), ref is part of the type, thus ref real, and subst must be explicitly given as an appropriate sort of proc. The separate specification part has vanished.

(Be careful with any comparison with today's languages: Algol 68's handling of the concept of 'reference' is not quite like that of current languages)

  • 2
    If I'm wrong about CPL being the first, I'd expect another member of the flurry of Algol-inspired languages from the 1960s.
    – dave
    Commented Feb 7, 2022 at 1:47
  • 4
    To some extent, but Algol 68 generally has one more ref in the type. An int is a number. A ref int is an integer variable. "int foo" declares foo with type reference-to-int; it is shorthand for "ref int foo = loc int, where '=' denotes identity, not assignment. There is no implication that 'foo' holds some sort of pointer; it is just (admirable) dogmatic recognition that a variable cannot 'be' a number.
    – dave
    Commented Feb 7, 2022 at 2:00
  • 5
    C++ somehow avoids the need to explain "int foo" as a shorthand for int & foo = *reinterpret_cast< int* >(alloca(sizeof(int)))
    – Leo B.
    Commented Feb 7, 2022 at 6:29
  • 2
    Because, of course, C++ confuses "integer" with "variable". FWIW, Java is even more confused. The specification actually contains the words "constant variable".
    – dave
    Commented Feb 7, 2022 at 13:19
  • 1
    @another-dave So does the Common Lisp specification: lispworks.com/documentation/HyperSpec/Body/…
    – texdr.aft
    Commented Feb 7, 2022 at 15:15

The origin of inline parameter-type annotations is in 1940, with Alonzo Church's formulation of the simply-typed lambda calculus. I believe this was also the introduction of type annotations of any kind within the program, so inline annotations were the original form, not a more modern development.

In Church's notation, types were given to parameters using subscripts directly after the variable name: λxᵦy defines a function whose parameter x has type β and returns the evaluation of y, λfᵨᵦy a function whose parameter f is itself a function from β to ρ, and so on (a more typical notation now would be λf:(β → ρ).y).

For example, the paper gives this implementation of the (Church) integer successor function (the function that returns its argument plus one):

λn₍ₐₐ₎₍ₐₐ₎λfₐₐλxₐ(f(n f x))

Here all three parameters have inline type annotations:

  • x has type a, for some a,
  • f is a function from a to a,
  • n is a function that accepts a function from a to a, and returns another function from a to a (this is the type of Church integers)

Zero is also given as λfₐₐλxₐx, so (λn₍ₐₐ₎₍ₐₐ₎λfₐₐλxₐ(f(nfx))) (λfₐₐλxₐx) is a complete program that evaluates to 1 (or λfₐₐλxₐfx).

Though not implemented at the time, the lambda calculus is a working programming language, capable of expressing any computation and of being executed by a machine, albeit a language that is very awkward to use and one that didn't anticipate the kinds of computers we use today or even in the 1960s. Complex-for-their-time programs had been written in the untyped language that performed mathematical algorithms. The simply-typed version satisfies all of the definitions and constraints in the question and includes the type information of formal parameters within the parameter list.

Alonzo Church, "A Formulation of the Simple Theory of Types", The Journal of Symbolic Logic, Vol. 5, No. 2. (Jun., 1940), pp. 56-68.

  • 1
    Quite interesting find.
    – Raffzahn
    Commented Feb 8, 2022 at 5:11
  • 1
    Huh. So the LISP paper introduced garbage collection and the simply typed lambda calculus paper introduced type annotations. Neat. :)
    – ssokolow
    Commented Feb 8, 2022 at 13:31
  • 1
    This is an unexpected type of answer. I have a smidgen of reluctance about it, since the lambda calculus was not intended as a programming language for computers (even though we now can recognize it as one). Still, a good answer!
    – dave
    Commented Feb 8, 2022 at 23:13
  • 1
    @another-dave Intent is a complex question, but undoubtedly it is one. The idea that a physical machine could follow instructions translated from the lambda calculus was known by Church by the time of the STLC paper, and later language designers were aware of the lambda calculus (certainly in the 1960s, postdating Lisp!). Commented Feb 8, 2022 at 23:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .