26

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

Ben Brocka
  • 2,751
  • 1
  • 19
  • 30
carinmeier
  • 455
  • 1
  • 4
  • 6
  • Assembler uses MOV instead of LET from 1954. Isn't it enough? – Gangnus Feb 22 '14 at 22:44
  • 1
    LISP is old enough to be a good candidate. – mouviciel Jul 02 '14 at 09:05
  • 3
    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
  • 2
    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
  • [Peter Landin](https://en.wikipedia.org/wiki/Peter_Landin)'s "Correspondence Between ALGOL 60 and Church's Lambda Notation" was published in 1965 and had *" `let`"* in it. His 1964 "The mechanical evaluation of expressions" already has *" `where`"* which is the same as *`let`*, just with the flipped order. – Will Ness Oct 16 '20 at 07:04

5 Answers5

40

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.

Greg
  • 501
  • 3
  • 2
  • 12
    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 08 '13 at 08:12
  • 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 08 '13 at 12:54
  • 7
    `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 08 '13 at 16:43
  • 3
    "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 09 '13 at 12:00
  • 1
    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 09 '13 at 12:42
  • @SK-logic The title of the question was "In what programming language..". – Johan Karlsson Jul 15 '14 at 09:45
  • The question in the title isn't the same question as in the body. Question in title asks for first use of let in programming language and the question in the body is about the origins of let. Those two questions have two different answers. The wrong assumption made by the topicstarter is that the modern use of let is inspired upon older use of let in earlier programming languages. Whereas the use of let in languages like haskell would have happened regardless of the use of let in basic, because functional languages have a lot of their origins from math, where let is commonly used. – Pieter B Aug 20 '14 at 11:12
  • I'm upvoting this answer cause it is correct, and all the negative comments are complete makarky. – user949300 Jan 23 '18 at 06:45
  • @Greg "x be 3" is the same tense as "x is 3" (present), but a different mood (subjunctive rather than indicative). – Graham Lee Mar 22 '18 at 12:22
31

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

(λx.M)N

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

Petr
  • 5,507
  • 3
  • 29
  • 46
  • +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 08 '13 at 17:32
  • 3
    @Giorgio To quote [The New hacker's dictionary](http://books.google.cz/books?id=g80P_4v4QbIC&pg=PA432&redir_esc=y#v=onepage&q&f=false): _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](https://en.wikipedia.org/wiki/Syntactic_sugar) also has a nice explanation. – Petr Apr 08 '13 at 17:56
  • 3
    interesting stuff but hardly related to `let`'s introduction – wirrbel Jun 13 '13 at 07:14
  • 2
    It is a well written answer, but it does not answer the original question. – Johan Karlsson Jul 15 '14 at 10:10
  • 1
    @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 Jul 15 '14 at 17:38
  • @JohanKarlsson There are 2 original questions and 1 incorrect assumption by the topicstarter. The incorrect assumption is that the first use of "let" in a programming language must be the origin of "let"-use in Lisp, Clojure, and Haskell. – Pieter B Aug 20 '14 at 11:19
  • I'm just curious to know how the word "let" (meaning "to permit" or "to allow") came to be associated with mathematical or programming logic. Does anybody know the real etymology behind it? –  Nov 21 '15 at 05:22
  • @Alhadis My guess would be that it's simply using _let_ in its imperative form. Wiktionary also describes one usage of _let_: _used to introduce an imperative in the first or third person_ , see 6th point of [let - verb](https://en.wiktionary.org/w/index.php?title=let&oldid=35361964#Verb). – Petr Nov 21 '15 at 10:09
  • I considered that, but even within that context, it still struck me as a decidedly... vague way of declaring an arbitrary value. Guess I'm still inclined to stick to my prior irreverent theory that `let` is a contracted form of "let's assume that we have a variable named x that happens to equal..." –  Nov 21 '15 at 10:36
22

Lisp is the oldest language of these having LET now. 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]
END

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

TRANSFER a TO b and MOVE a TO b

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
Gangnus
  • 2,805
  • 4
  • 21
  • 31
14

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. :-)

C. K. Young
  • 2,427
  • 19
  • 22
  • 4
    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 08 '13 at 09:04
  • [Peter Landin](https://en.wikipedia.org/wiki/Peter_Landin)'s "Correspondence Between ALGOL 60 and Church's Lambda Notation" was published in 1965 and had "let" in it. His 1964 "The mechanical evaluation of expressions" already has `where`. – Will Ness Oct 15 '20 at 20:15
9

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))
Rainer Joswig
  • 2,190
  • 11
  • 17
  • was `let` always lexically scoped in Lisp dialects? – wirrbel Jun 13 '13 at 07:15
  • 1
    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. – TaylanKammer Aug 20 '14 at 08: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. – TaylanKammer Aug 20 '14 at 08:49