Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I was wondering about the origins of the "let" used in Lisp, Clojure, and Haskell. Does anyone know which language it appeared in first?

share|improve this question
Assembler uses MOV instead of LET from 1954. Isn't it enough? –  Gangnus Feb 22 '14 at 22:44
LISP is old enough to be a good candidate. –  mouviciel Jul 2 '14 at 9:05
for any question "In what programming language did X first appear" lisp is a pretty good guess for a correct answer –  Zachary K Jul 15 '14 at 10:21
let origins are from math, not from other programming languages. –  Pieter B Aug 20 '14 at 11:05
You make the incorrect assumption that the first use of "let" in a programminglanguage is the origin of "let"-use in Lisp, Clojure, and Haskell. –  Pieter B Aug 20 '14 at 11:20

5 Answers 5

Well, BASIC had 'LET' for assignment as part of the syntax from the start in 1964, so that would predate the use of 'let' in Lisp, which as Chris Jester-Young points out didn't appear until the 1970s according to Evolution of Lisp.

I don't believe COBOL, Fortran, or ALGOL have 'LET' in their syntax either. So I'm going to go with BASIC.

share|improve this answer
But semantics is very different - let in basic is not a lexically scoped binding. So, the correct answer would be something like "it first appeared in English, before 12th century". –  SK-logic Apr 8 '13 at 8:12
But the questions is: What programming language did the "let" first appear? I don't really consider English a programming language (at least in this context). –  Greg Apr 8 '13 at 12:54
let in this context (let x is something in the following expression) first appeared in mathematical texts in English, and this is where it came into programming. I see no difference between formal systems - mathematical languages, programming languages, whatever else - they're all the same. –  SK-logic Apr 8 '13 at 16:43
"let x is 3" is not proper grammar. You would never see that in any English text book. You have the wrong tense of the verb "to be". It should be "let x be 3" or "let x equal 3". Either way, semantics or not, the question author was asking for a programming language. So unless you know of a computer that takes English instructions that predates BASIC, I'm not buying it. Otherwise, we could have just answered "psuedo-code" and that would be valid, but wouldn't honor the spirit of her question. –  Greg Apr 9 '13 at 12:00
of course I used ML notation, and I meant equals, not is. And, yes, pseudo-code is the best answer so far. –  SK-logic Apr 9 '13 at 12:42

I'd like to add a theoretical point of view: In classical lambda calculi, let is just syntactic sugar. For example

let x = N in M

can be rewritten simply as


So its first appearance in early (functional) languages isn't that interesting.

However, it become very important with the invention of Hindley-Milner type system and its type inference algorithm. In this type system let is indispensable, because it's polymorphic (unlike λ-abstraction in HM). For example, consider this simple expression:

let id = λx . x in id id

Here id is polymorphic, it has type ∀α.α → α, and therefore id id type-checks - it's type is id id : τ → τ for arbitrary τ. (For the first id we assign τ → τ to α and for the second id we assign τ for α.)

However, we can't rewrite it using λ abstraction and application. Expression

(λid . id id)(λx.x)

doesn't type-check, because within the first λ abstraction id must be assigned a monomorphic type id : σ for some σ, and there is no σ such that we could apply id : σ to id : σ.

You can try this yourself in Haskell. While let id = \x -> x in id id :: t -> t type-checks, typing (\id -> id id)(\x -> x) fails with

Occurs check: cannot construct the infinite type: t0 = t0 -> t0
In the first argument of id, namely id
In the expression: id id
In the expression: \id -> id id

share|improve this answer
+1 for a very interesting answer. As a side topic, if you know one, could you post (in a comment, since this is not related to the main question) a reference to a rigorous definition of "syntactic sugar". –  Giorgio Apr 8 '13 at 17:32
@Giorgio To quote The New hacker's dictionary: Features added to a language or other formalism to make it "sweeter" for humans, features which do not affect the expressiveness of the formalism. Used esp. when there is an obvious and trivial translation of the "sugar" feature into other constructs already present in the notation. C's a[i] notation is syntactic sugar for *(a + i). The Wikipedia article also has a nice explanation. –  Petr Pudlák Apr 8 '13 at 17:56
interesting stuff but hardly related to let's introduction –  wirrbel Jun 13 '13 at 7:14
It is a well written answer, but it does not answer the original question. –  Johan Karlsson Jul 15 '14 at 10:10
@JohanKarlsson I'm not claiming it is a direct answer, but I think this is also relevant to the topic. In particular why was let introduced, as the question starts with I was wondering about the origins of the "let" ... –  Petr Pudlák Jul 15 '14 at 17:38

Lisp is the oldest language of these having LET. But BASIC was the first that got it, for Lisp had obtained it much later.

In Ada Lovelace Analytical Engine (1843) - no LET, a program looks as:

N0 6 N1 1 N2 1 × L1 L0 S1  L0 L2 S0 L2 L0 CB?11 '

In Plankalkül of Zuse (1943-45) the program looks:

P1 max3 (V0[:8.0],V1[:8.0],V2[:8.0]) → R0[:8.0]
max(V0[:8.0],V1[:8.0]) → Z1[:8.0]
max(Z1[:8.0],V2[:8.0]) → R0[:8.0]

Short Code was proposed by John Mauchly in 1949

X3 =  (  X1 +  Y1 )  /  X1 * Y1   

Intermediate PL of Burks, 1950, used for assignment ->

Rutishauser in 1952 used =>=

Böhms compiler, 1952, used ->

At the University of Manchester, Alick Glennie developed Autocode in the early 1950s. The first code and compiler was developed in 1952 for the Mark 1 computer at the University of Manchester and is considered to be the first compiled high-level programming language. Again, -> for assignment

Charles Adams, FORTRAN 0 of Backus's group , Brooker's Autocode 2, ПП1 of Lubimsky and Kamynin; all in 1954, again =

BACAIC (Grems, Porter), 1954, * for assignment!

Kompiler, ADES, 1955, =

IT, 1956, <-

FORTRAN, 1957, =

AT-3 (1956), Math-Matic (1957), again =,

but Flow-Matic in 1957 had two assignments, and both are in words


Bauer and Samelson's machine, 1957: =>

Sorry, I can't cover all languages between 1957 and 1964, but greater languages

1957 - COMTRAN (forerunner to COBOL)
1958 - LISP
1958 - ALGOL 58
1959 - FACT (forerunner to COBOL)
1959 - COBOL
1959 - RPG
1962 - APL
1962 - Simula
1962 - SNOBOL
1963 - CPL (forerunner to C)

have not LET for assignment. Or had not, in the case of LISP.

Dartmouth BASIC is the original version of the BASIC programming language. The first interactive version was made available to general users in June 1964;

 LET / = — assign formula results to a variable
share|improve this answer

Well, between those three, Lisp definitely had it first. Haskell came about in the 80s, and Clojure in the 00s, and let had been around long before either of those dates. :-)

As to whether Lisp was the language to have invented it, I can't vouch for that yet, but I'll do some research and see. :-)

Update: According to Evolution of Lisp (see page 46), it mentioned that let was invented in the 70s:

LET—itself a macro first invented and reinvented locally at each site—was a late-comer to the MacLisp world; according to Lisp Archive, it was retroactively absorbed into PDP-10 MacLisp from Lisp-Machine Lisp in 1979 at the same time as DEFMACRO and the complex Lisp Machine DEFUN argument syntax.

Still doesn't quite answer whether it was invented in another language earlier, of course, but still another data point. :-)

share|improve this answer
ML was also developed during the 70s so it might be that the idea was introduced in both ML and Lisp in that period. –  Giorgio Apr 8 '13 at 9:04

The first Revised Scheme report AIM-452 from January 1978 has LET. Page 9.

note that Lisp used earlier a different construct PROG to introduce local variables.

(let ((a 1)
      (b 1))
  (+ a b))

would have been written earlier approximately as

(prog (a b)
  (setq a 1)
  (setq b 1)
  (+ a b))
share|improve this answer
was let always lexically scoped in Lisp dialects? –  wirrbel Jun 13 '13 at 7:15
AIM-452 is the first revised report on Scheme. The first report is AIM-349 from 1975. And AIM-848 is the revised revised report. And the one after that, called the "revised^3" report (i.e. first one to use the "R^nRS" naming) was the first that was not an AIM but an actual language specification. Googling around a bit will find you the PDFs of all these documents so you can read them for yourself. If you want to go further back you can find an old MacLisp manual from the Software Preservation Group, and maybe you'll be able to find some LISP 1.5 reports too. –  TaylanUB Aug 20 '14 at 8:11
@wirrbel, it seems let is about as old as lexical scoping (Scheme, '75), and it took a while for lexical scoping to gain acceptance, so I would guess that the first instances of let were in the context of dynamically scoped Lisps. Today, Emacs Lisp still has dynamic scope by default, with lambda and let (the latter sugar for the former anyway) binding their parameters dynamically. –  TaylanUB Aug 20 '14 at 8:49

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.