Eu estava pensando sobre as origens do "let" usado em Lisp, Clojure e Haskell. Alguém sabe em que idioma apareceu primeiro?
Eu estava pensando sobre as origens do "let" usado em Lisp, Clojure e Haskell. Alguém sabe em que idioma apareceu primeiro?
Respostas:
Bem, o BASIC tinha LET
para atribuição como parte da sintaxe desde o início de 1964, de modo que seria anterior ao uso do let
Lisp, que, como Chris Jester-Young aponta, não apareceu até a década de 1970, de acordo com a Evolution of Lisp .
Também não acredito que COBOL, Fortran ou ALGOL tenham LET
sua sintaxe. Então, eu vou com o BASIC.
let
no básico, não é uma ligação com escopo lexicamente. Portanto, a resposta correta seria algo como "apareceu pela primeira vez em inglês antes do século XII".
let
nesse contexto ( let
x is
algo que in
a expressão a seguir) apareceu pela primeira vez em textos matemáticos em inglês, e foi aí que ele entrou na programação. Não vejo diferença entre sistemas formais - linguagens matemáticas, linguagens de programação, o que quer que seja - são todos iguais.
equals
, não is
. E, sim, o pseudo-código é a melhor resposta até agora.
Eu gostaria de acrescentar um ponto de vista teórico: no cálculo lambda clássico, let
é apenas açúcar sintático. Por exemplo
let x = N in M
pode ser reescrito simplesmente como
(λx.M)N
Portanto, sua primeira aparição em idiomas iniciais (funcionais) não é tão interessante.
No entanto, tornou-se muito importante com a invenção do sistema do tipo Hindley-Milner e seu algoritmo de inferência de tipo. Nesse sistema de tipos let
é indispensável, porque é polimórfico (diferentemente da abstração λ no HM). Por exemplo, considere esta expressão simples:
let id = λx . x in id id
Aqui id
é polimórfico, tem tipo ∀α.α → α
e, portanto id id
, verifica o tipo - é do tipo id id : τ → τ
τ arbitrário. (Para o primeiro id
que atribuímos τ → τ
a α
e para o segundo id
que atribuímos τ
para α
.)
No entanto, não podemos reescrevê-lo usando λ abstração e aplicativo. Expressão
(λid . id id)(λx.x)
não digite-check, porque dentro da primeira abstração λ id
deve ser atribuído um tipo monomórfica id : σ
por algum σ, e não há σ tal que pudéssemos aplicar id : σ
para id : σ
.
Você pode tentar isso sozinho em Haskell. Enquanto let id = \x -> x in id id :: t -> t
verifica o tipo, a digitação (\id -> id id)(\x -> x)
falha com
Ocorre verificação: não é possível construir o tipo infinito:
t0 = t0 -> t0
no primeiro argumento deid
, ou seja,id
na expressão:id id
na expressão:\id -> id id
a[i]
notação de C é o açúcar sintático para *(a + i)
. O artigo da Wikipedia também tem uma boa explicação.
let
's introdução
let
introduzido, como a questão começa com Eu estava pensando sobre as origens do "vamos" ...
Lisp é a língua mais antiga de quem deixou LET agora . Mas o BASIC foi o primeiro a obtê-lo, pois Lisp o obteve muito mais tarde.
No Ada Lovelace Analytical Engine (1843) - sem LET, um programa se parece com:
N0 6 N1 1 N2 1 × L1 L0 S1 L0 L2 S0 L2 L0 CB?11 '
Em Plankalkül de Zuse (1943-45), o programa parece:
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 foi proposto por John Mauchly em 1949
X3 = ( X1 + Y1 ) / X1 * Y1
PL intermediário de Burks, 1950, usado para atribuição ->
Rutishauser em 1952 usado =>=
Compilador Böhms, 1952, usado ->
Na Universidade de Manchester, Alick Glennie se desenvolveu Autocode
no início dos anos 50. O primeiro código e compilador foi desenvolvido em 1952 para o computador Mark 1 na Universidade de Manchester e é considerado a primeira linguagem de programação de alto nível compilada. Novamente, ->
para atribuição
Charles Adams, FORTRAN 0 do grupo de Backus, Brooker Autocode 2, ПП1 de Lubimsky e Kamynin; tudo em 1954, novamente=
BACAIC (Grems, Porter), 1954, *
para atribuição!
Kompiler, ADES, 1955, =
IT, 1956, <-
FORTRAN, 1957, =
AT-3 (1956), Math-Matic (1957), novamente =
,
mas Flow-Matic em 1957 tinha duas atribuições, e ambas estão em palavras
TRANSFER a TO b
e MOVE a TO b
A máquina de Bauer e Samelson, 1957: =>
Desculpe, não posso cobrir todos os idiomas entre 1957 e 1964, mas idiomas maiores
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)
não deixe para atribuição. Ou não , no caso do LISP.
Dartmouth BASIC é a versão original da linguagem de programação BASIC. A primeira versão interativa foi disponibilizada para usuários gerais em junho de 1964 ;
LET / = — assign formula results to a variable
Bem, entre os três, Lisp definitivamente teve primeiro. Haskell surgiu nos anos 80 e Clojure nos anos 2000 e let
já existia muito antes de qualquer uma dessas datas. :-)
Quanto à questão de saber se o Lisp foi o idioma que o inventou, ainda não posso garantir isso, mas vou fazer algumas pesquisas e ver. :-)
Atualização: De acordo com o Evolution of Lisp (na página 46), mencionou que let
foi inventado nos anos 70:
LET
- uma macro inventada e reinventada localmente em cada local - era uma das que chegavam tarde ao mundo MacLisp; de acordo com o Lisp Archive, foi absorvido retroativamente no PDP-10 MacLisp do Lisp-Machine Lisp em 1979, ao mesmo tempo em queDEFMACRO
a complexaDEFUN
sintaxe de argumentos da Lisp Machine .
Ainda não responde bem se foi inventado em outro idioma anteriormente, é claro, mas ainda outro ponto de dados. :-)
O primeiro relatório revisado do esquema AIM-452 de janeiro de 1978 possui LET
. Página 9.
note que o Lisp usou anteriormente uma construção diferente PROG
para introduzir variáveis locais.
(let ((a 1)
(b 1))
(+ a b))
teria sido escrito anteriormente aproximadamente como
(prog (a b)
(setq a 1)
(setq b 1)
(+ a b))
let
sempre foi escopo lexicamente nos dialetos Lisp?
let
é tão antigo quanto o escopo lexical (Scheme, '75), e demorou um tempo para o escopo lexical obter aceitação, então eu acho que as primeiras instâncias let
foram no contexto de Lisps com escopo dinâmico. Hoje, o Emacs Lisp ainda tem escopo dinâmico por padrão, com lambda
e let
(o último açúcar para o primeiro de qualquer maneira) vinculando seus parâmetros dinamicamente.