Tôi đã tự hỏi về nguồn gốc của "cho phép" được sử dụng trong Lisp, Clojure và Haskell. Có ai biết nó xuất hiện trong ngôn ngữ nào đầu tiên không?
Tôi đã tự hỏi về nguồn gốc của "cho phép" được sử dụng trong Lisp, Clojure và Haskell. Có ai biết nó xuất hiện trong ngôn ngữ nào đầu tiên không?
Câu trả lời:
Vâng, BASIC đã được chỉ LET
định như là một phần của cú pháp từ đầu năm 1964, do đó, điều đó sẽ có trước việc sử dụng let
trong Lisp, như Chris Jester-Young chỉ ra đã không xuất hiện cho đến những năm 1970 theo Evolution of Lisp .
Tôi cũng không tin rằng COBOL, Fortran hoặc ALGOL có LET
cú pháp của họ. Vì vậy, tôi sẽ đi với BASIC.
let
về cơ bản không phải là một ràng buộc phạm vi từ vựng. Vì vậy, câu trả lời đúng sẽ là một câu như "nó xuất hiện lần đầu tiên bằng tiếng Anh, trước thế kỷ 12".
let
trong bối cảnh này ( let
x is
một cái gì đó in
biểu thức sau) lần đầu tiên xuất hiện trong các văn bản toán học bằng tiếng Anh, và đây là nơi nó được đưa vào lập trình. Tôi thấy không có sự khác biệt giữa các hệ thống chính thức - ngôn ngữ toán học, ngôn ngữ lập trình, bất cứ điều gì khác - tất cả đều giống nhau.
equals
không is
. Và, vâng, mã giả là câu trả lời tốt nhất cho đến nay.
Tôi muốn thêm một quan điểm lý thuyết: Trong tính toán lambda cổ điển, let
chỉ là đường cú pháp. Ví dụ
let x = N in M
có thể được viết lại đơn giản như
(λx.M)N
Vì vậy, sự xuất hiện đầu tiên của nó trong các ngôn ngữ (chức năng) sớm không thú vị.
Tuy nhiên, nó trở nên rất quan trọng với việc phát minh ra hệ thống loại Hindley-Milner và thuật toán suy luận kiểu của nó. Trong loại hệ thống let
này là không thể thiếu, bởi vì nó là đa hình (không giống như trừu tượng in trong HM). Ví dụ, hãy xem xét biểu thức đơn giản này:
let id = λx . x in id id
Đây id
là dạng đa hình, nó có kiểu ∀α.α → α
và do đó id id
kiểm tra kiểu - kiểu này là id id : τ → τ
tùy ý. (Đối với lần đầu tiên id
chúng ta gán τ → τ
cho α
và cho lần thứ hai id
chúng ta gán τ
cho α
.)
Tuy nhiên, chúng tôi không thể viết lại bằng cách sử dụng trừu tượng hóa và ứng dụng. Biểu hiện
(λid . id id)(λx.x)
không gõ kiểm tra, bởi vì trong trừu tượng λ đầu tiên id
phải được chỉ định một loại monomorphic id : σ
đối với một số σ, và không có σ như vậy mà chúng ta có thể áp dụng id : σ
để id : σ
.
Bạn có thể thử điều này trong Haskell. Trong khi let id = \x -> x in id id :: t -> t
kiểm tra kiểu, gõ (\id -> id id)(\x -> x)
không thành công với
Kiểm tra xảy ra: không thể xây dựng kiểu vô hạn:
t0 = t0 -> t0
Trong đối số đầu tiên củaid
, cụ thể làid
Trong biểu thức:id id
Trong biểu thức:\id -> id id
a[i]
Ký hiệu C là đường cú pháp cho *(a + i)
. Bài viết Wikipedia cũng có một lời giải thích tốt đẹp.
let
giới thiệu
let
giới thiệu, khi câu hỏi bắt đầu với tôi đã tự hỏi về nguồn gốc của "hãy" ...
Lisp là ngôn ngữ lâu đời nhất trong số này có LET bây giờ . Nhưng BASIC là người đầu tiên nhận được nó, vì Lisp đã có được nó sau đó rất nhiều.
Trong Ada Lovelace Phân tích Công cụ (1843) - không có LET, một chương trình trông như:
N0 6 N1 1 N2 1 × L1 L0 S1 L0 L2 S0 L2 L0 CB?11 '
Trong Plankalkül of Zuse (1943-45), chương trình có vẻ:
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
Mã ngắn được đề xuất bởi John Mauchly vào năm 1949
X3 = ( X1 + Y1 ) / X1 * Y1
PL trung gian của Burks, 1950, được sử dụng để chuyển nhượng ->
Năm 1952 được sử dụng =>=
Trình biên dịch Böhms, 1952, được sử dụng ->
Tại Đại học Manchester, Alick Glennie đã phát triển Autocode
vào đầu những năm 1950. Mã và trình biên dịch đầu tiên được phát triển vào năm 1952 cho máy tính Mark 1 tại Đại học Manchester và được coi là ngôn ngữ lập trình cấp cao được biên dịch đầu tiên. Một lần nữa, ->
cho nhiệm vụ
Charles Adams, FORTRAN 0 trong nhóm của Backus, Autocode 2, Brooks1 của Lubimsky và Kamynin; tất cả vào năm 1954, một lần nữa=
BACAIC (Grems, Porter), 1954, *
để chuyển nhượng!
Máy xúc lật, ADES, 1955, =
CNTT, 1956, <-
FORTRAN, 1957, =
AT-3 (1956), Math-Matic (1957), một lần nữa =
,
nhưng Flow-Matic năm 1957 có hai bài tập và cả hai đều bằng chữ
TRANSFER a TO b
và MOVE a TO b
Máy của Bauer và Samelson, 1957: =>
Xin lỗi, tôi không thể bao gồm tất cả các ngôn ngữ trong khoảng thời gian từ 1957 đến 1964, nhưng các ngôn ngữ lớn hơn
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)
chưa LET cho nhiệm vụ. Hoặc không , trong trường hợp LISP.
Dartmouth BASIC là phiên bản gốc của ngôn ngữ lập trình BASIC. Phiên bản tương tác đầu tiên được cung cấp cho người dùng phổ thông vào tháng 6 năm 1964 ;
LET / = — assign formula results to a variable
Chà, giữa ba người đó, Lisp chắc chắn đã có nó trước. Haskell xuất hiện vào những năm 80 và Clojure vào những năm 00, và let
đã tồn tại rất lâu trước một trong những ngày đó. :-)
Là để cho dù Lisp là các ngôn ngữ đã phát minh ra nó, tôi không thể xác minh cho rằng chưa, nhưng tôi sẽ làm một số nghiên cứu và xem. :-)
Cập nhật: Theo Evolution of Lisp (xem trang 46), nó đã đề cập đến việc let
được phát minh vào những năm 70:
LET
Chính mình là một macro đầu tiên được phát minh và phát minh lại tại địa phương tại mỗi trang web, đó là một người đến muộn trong thế giới MacLisp; theo Lisp Archive, nó đã được hấp thụ hồi tố vào PDP-10 MacLisp từ Lisp-Machine Lisp vào năm 1979 cùng lúc với cú pháp đối sốDEFMACRO
phức tạp của Lisp MachineDEFUN
.
Vẫn không hoàn toàn trả lời liệu nó đã được phát minh bằng ngôn ngữ khác trước đó, tất nhiên, nhưng vẫn là một điểm dữ liệu khác. :-)
Báo cáo Đề án sửa đổi đầu tiên AIM-452 từ tháng 1 năm 1978 đã có LET
. Trang 9.
lưu ý rằng Lisp đã sử dụng trước đó một cấu trúc khác PROG
để giới thiệu các biến cục bộ.
(let ((a 1)
(b 1))
(+ a b))
sẽ được viết sớm hơn khoảng
(prog (a b)
(setq a 1)
(setq b 1)
(+ a b))
let
luôn lexically scoped trong phương ngữ Lisp?
let
cũ như phạm vi từ vựng (Scheme, '75), và phải mất một thời gian để phạm vi từ vựng để được chấp nhận, vì vậy tôi đoán rằng những trường hợp đầu tiên let
là trong bối cảnh của Lisps có phạm vi động. Ngày nay, Emacs Lisp vẫn có phạm vi động theo mặc định, lambda
và let
(đường sau cho đường trước dù sao) ràng buộc các tham số của chúng một cách linh hoạt.