¿En qué lenguaje de programación apareció "let" por primera vez?

24

Me preguntaba sobre los orígenes del "let" utilizado en Lisp, Clojure y Haskell. ¿Alguien sabe en qué idioma apareció primero?

carinmeier
fuente
Assembler usa MOV en lugar de LET desde 1954. ¿No es suficiente?
Gangnus
1
LISP tiene la edad suficiente para ser un buen candidato.
mouviciel
2
para cualquier pregunta "En qué lenguaje de programación apareció X por primera vez" lisp es una suposición bastante buena para una respuesta correcta
Zachary K
2
Deje que los orígenes sean matemáticos, no de otros lenguajes de programación.
Pieter B
Asume incorrectamente que el primer uso de "let" en un lenguaje de programación es el origen del uso "let" en Lisp, Clojure y Haskell.
Pieter B

Respuestas:

41

Bueno, BASIC tenía LETuna asignación como parte de la sintaxis desde el comienzo en 1964, por lo que sería anterior al uso de letLisp, que, como señala Chris Jester-Young, no apareció hasta la década de 1970 según Evolution of Lisp .

Tampoco creo que COBOL, Fortran o ALGOL tengan LETen su sintaxis. Entonces voy a ir con BASIC.

Greg
fuente
11
Pero la semántica es muy diferente: leten básica no es un enlace léxico. Entonces, la respuesta correcta sería algo así como "apareció por primera vez en inglés, antes del siglo XII".
SK-logic
12
Pero la pregunta es: ¿en qué lenguaje de programación apareció primero el "dejar"? Realmente no considero que el inglés sea un lenguaje de programación (al menos en este contexto).
Greg
77
leten este contexto ( letx isalgo, inla siguiente expresión) apareció por primera vez en textos matemáticos en inglés, y aquí es donde entró en la programación. No veo diferencia entre los sistemas formales: lenguajes matemáticos, lenguajes de programación, lo que sea, son todos iguales.
SK-logic
3
"let x is 3" no es una gramática adecuada. Nunca verías eso en ningún libro de texto en inglés. Tienes el tiempo equivocado del verbo "to be". Debe ser "let x be 3" o "let x igual a 3". De cualquier manera, semántica o no, el autor de la pregunta estaba pidiendo un lenguaje de programación. Entonces, a menos que sepa de una computadora que toma instrucciones en inglés anteriores a BASIC, no la compraré. De lo contrario, podríamos haber respondido "psuedo-code" y eso sería válido, pero no honraría el espíritu de su pregunta.
Greg
1
por supuesto, usé la notación ML, y quise decir que equalsno is. Y sí, el pseudocódigo es la mejor respuesta hasta ahora.
SK-logic
30

Me gustaría agregar un punto de vista teórico: en los cálculos lambda clásicos, letes solo azúcar sintáctico. Por ejemplo

let x = N in M

puede reescribirse simplemente como

(λx.M)N

Por lo tanto, su primera aparición en los primeros lenguajes (funcionales) no es tan interesante.

Sin embargo, se vuelve muy importante con la invención del sistema de tipos Hindley-Milner y su algoritmo de inferencia de tipos. En este tipo de sistema letes indispensable, porque es polimórfico (a diferencia de la abstracción λ en HM). Por ejemplo, considere esta simple expresión:

let id = λx . x in id id

Aquí ides polimórfico, tiene tipo ∀α.α → αy, por lo tanto id id, verificaciones de tipo: su tipo es id id : τ → τpara τ arbitrario. (Por primera idasignamos τ → τa αy para la segunda idasignamos τa α.)

Sin embargo, no podemos reescribirlo usando la abstracción λ y la aplicación. Expresión

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

no escribir-cheque, porque dentro de la primera abstracción λ idse le debe asignar un tipo monomórfica id : σpara algunos σ, y no hay σ tal que podríamos aplicar id : σa id : σ.

Puedes probar esto tú mismo en Haskell. Mientras se let id = \x -> x in id id :: t -> tverifican los tipos, la escritura (\id -> id id)(\x -> x)falla con

Se produce la comprobación: no se puede construir el tipo infinito: t0 = t0 -> t0
en el primer argumento de id, a saber, id
en la expresión: id id
en la expresión:\id -> id id

Petr Pudlák
fuente
+1 para una respuesta muy interesante. Como tema secundario, si conoce uno, ¿podría publicar (en un comentario, ya que esto no está relacionado con la pregunta principal) una referencia a una definición rigurosa de "azúcar sintáctico".
Giorgio
3
@Giorgio Para citar El diccionario del nuevo hacker : características agregadas a un lenguaje u otro formalismo para hacerlo "más dulce" para los humanos, características que no afectan la expresividad del formalismo. Usado esp. cuando hay una traducción obvia y trivial de la característica "azúcar" en otras construcciones ya presentes en la notación. La a[i]notación de C es azúcar sintáctica para *(a + i). El artículo de Wikipedia también tiene una buena explicación.
Petr Pudlák
3
cosas interesantes, pero apenas relacionadas con letla introducción
wirrbel
2
Es una respuesta bien escrita, pero no responde la pregunta original.
Johan Karlsson
1
@JohanKarlsson No estoy afirmando que sea una respuesta directa, pero creo que esto también es relevante para el tema. En particular, por qué se letpresentó, ya que la pregunta comienza cuando me preguntaba sobre los orígenes del "let" ...
Petr Pudlák
22

Lisp es el idioma más antiguo de estos que tiene LET ahora . Pero BASIC fue el primero que lo consiguió, porque Lisp lo había obtenido mucho más tarde.

En Ada Lovelace Analytical Engine (1843), sin LET, un programa se ve así:

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

En Plankalkül of Zuse (1943-45) el programa se ve:

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

Código corto fue propuesto por John Mauchly en 1949

X3 =  (  X1 +  Y1 )  /  X1 * Y1   

PL intermedio de Burks, 1950, utilizado para asignación ->

Rutishauser en 1952 usado =>=

Compilador de Böhms, 1952, usado ->

En la Universidad de Manchester, Alick Glennie se desarrolló Autocodea principios de la década de 1950. El primer código y compilador se desarrolló en 1952 para la computadora Mark 1 de la Universidad de Manchester y se considera el primer lenguaje de programación compilado de alto nivel. De nuevo, ->para asignación

Charles Adams, FORTRAN 0 del grupo de Backus, Autocode 2 de Brooker, ПП1 de Lubimsky y Kamynin; todo en 1954, nuevamente=

BACAIC (Grems, Porter), 1954, *para asignación.

Kompiler, ADES, 1955, =

IT, 1956, <-

FORTRAN, 1957, =

AT-3 (1956), Math-Matic (1957), de nuevo =,

pero Flow-Matic en 1957 tenía dos tareas, y ambas están en palabras

TRANSFER a TO b y MOVE a TO b

La máquina de Bauer y Samelson, 1957: =>


Lo sentimos, no puedo abarcar todos los idiomas entre 1957 y 1964, pero los idiomas más grandes

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)

no he dejado para la asignación. O no lo había hecho , en el caso de LISP.


Dartmouth BASIC es la versión original del lenguaje de programación BASIC. La primera versión interactiva se puso a disposición de los usuarios generales en junio de 1964 ;

 LET / = — assign formula results to a variable
Gangnus
fuente
14

Bueno, entre esos tres, Lisp definitivamente lo tuvo primero. Haskell surgió en los años 80 y Clojure en los años 00, y lethabía existido mucho antes de cualquiera de esas fechas. :-)

En cuanto a si Lisp fue el lenguaje que lo inventó, todavía no puedo responder por eso, pero investigaré un poco y veré. :-)

Actualización: Según Evolution of Lisp (ver página 46), mencionó que letfue inventado en los años 70:

LET—En sí mismo, una macro inventada por primera vez y reinventada localmente en cada sitio— fue un recién llegado al mundo de MacLisp; según Lisp Archive, fue absorbido retroactivamente en PDP-10 MacLisp desde Lisp-Machine Lisp en 1979 al mismo tiempo que DEFMACROla compleja DEFUNsintaxis de argumentos de Lisp Machine .

Todavía no responde si fue inventado en otro idioma antes, por supuesto, pero aún otro punto de datos. :-)

Chris Jester-Young
fuente
44
ML también se desarrolló durante los años 70, por lo que podría ser que la idea se introdujera tanto en ML como en Lisp en ese período.
Giorgio
9

El primer informe revisado del esquema AIM-452 de enero de 1978 tiene LET. Página 9.

tenga en cuenta que Lisp utilizó anteriormente una construcción diferente PROGpara introducir variables locales.

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

habría sido escrito anteriormente aproximadamente como

(prog (a b)
  (setq a 1)
  (setq b 1)
  (+ a b))
Rainer Joswig
fuente
¿ letsiempre fue examinado léxicamente en los dialectos de Lisp?
wirrbel
1
AIM-452 es el primer informe revisado sobre el Esquema. El primer informe es AIM-349 de 1975. Y AIM-848 es el informe revisado revisado. Y el siguiente, llamado informe "revisado ^ 3" (es decir, el primero en usar el nombre "R ^ nRS") fue el primero que no era un AIM sino una especificación de lenguaje real. Si buscas un poco en Google, encontrarás los archivos PDF de todos estos documentos para que puedas leerlos tú mismo. Si desea ir más atrás, puede encontrar un antiguo manual de MacLisp del Grupo de preservación de software, y tal vez también pueda encontrar algunos informes de LISP 1.5.
TaylanUB
@wirrbel, parece que letes casi tan antiguo como el alcance léxico (Scheme, '75), y tomó un tiempo para que el alcance léxico ganara aceptación, por lo que supongo que las primeras instancias letfueron en el contexto de Lisps con alcance dinámico. Hoy, Emacs Lisp todavía tiene un alcance dinámico por defecto, lambday let(el último azúcar para el primero de todos modos) vincula sus parámetros dinámicamente.
TaylanUB