“ let”首先以哪种编程语言出现?


24

我想知道Lisp,Clojure和Haskell中使用的“ let”的起源。有人知道它最初出现哪种语言吗?


汇编程序使用MOV代替了1954年的LET。这还不够吗?
Gangnus 2014年

1
LISP的年龄足以成为一个不错的候选人。
mouviciel 2014年

2
对于任何问题“ X最初以哪种编程语言出现”,Lisp都是对正确答案的很好猜测
Zachary K

2
让起源来自数学,而不是其他编程语言。
Pieter B

您做出了错误的假设,即在编程语言中首次使用“ let”是Lisp,Clojure和Haskell中“ let”使用的起源。
Pieter B

Answers:


41

好吧,BASICLET从1964年开始就必须将赋值作为语法的一部分,因此这要早于let在Lisp中使用,正如Chris Jester-Young指出的那样,直到1990年代才根据Lisp的演变出现

我也不相信COBOL,Fortran或ALGOL LET的语法也是如此。因此,我将选择BASIC。


11
但是语义是非常不同的- let从根本上讲,这不是一个词法范围的绑定。因此,正确的答案应该是“它在12世纪之前以英语首次出现”。
SK-logic

12
但是问题是:“ let”首先出现在哪种编程语言中?我真的不认为英语是一种编程语言(至少在这种情况下)。
格雷格,

7
let在这种情况下(letX is的东西in下面的表达式)在数学文最早出现在英语,这是它进入了编程。我认为形式系统之间没有什么区别-数学语言,编程语言等等-它们都是相同的。
SK-logic

3
“让x为3”不是正确的语法。您不会在任何英语教科书中看到它。您使用的动词“是”的时态错误。它应该是“ let x is 3”或“ let x equal 3”。无论是语义还是非语义,问题作者都在要求一种编程语言。因此,除非您知道使用BASIC之前的英语指令的计算机,否则我不会购买。否则,我们可能只回答了“伪代码”,这是有效的,但不尊重她的问题的实质。
格雷格2013年

1
当然,我使用ML表示法,而我的意思equals不是is。而且,是的,到目前为止,伪代码是最好的答案。
SK-logic

30

我想补充一下理论上的观点:在经典的λ结石中,let只是语法糖。例如

let x = N in M

可以简单地重写为

(λx.M)N

因此,它在早期(功能性)语言中的首次出现并不是那么有趣。

但是,随着Hindley-Milner类型系统及其类型推断算法的发明,这一点变得非常重要。在这种类型的系统let中必不可少,因为它是多态的(不同于HM中的λ-抽象)。例如,考虑以下简单表达式:

let id = λx . x in id id

id是多态的,它具有type ∀α.α → α,因此要进行id id类型检查-它的类型适用id id : τ → τ于任意τ。(对于第一个,id我们分配τ → τα,对于第二个,id我们分配τα。)

但是,我们无法使用λ抽象和应用程序对其进行重写。表达

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

没有类型检查,因为第一个λ抽象内id必须分配单态型id : σ的一些σ,并没有这样的σ,我们可以申请id : σid : σ

您可以在Haskell中自己尝试。在进行let id = \x -> x in id id :: t -> t类型检查时,键入(\id -> id id)(\x -> x)失败并显示

发生检查:不能构造无限类型:t0 = t0 -> t0
在的第一个参数中id,即id
在表达式中:id id
在表达式中:\id -> id id


+1是一个非常有趣的答案。作为附带主题,如果您知道的话,可以发表(在注释中,因为这与主要问题无关),以提及“句法糖”的严格定义。
Giorgio

3
@Giorgio引用《新黑客字典》语言或其他形式主义中增加的功能,使其对人类“更甜”,这些功能不会影响形式主义的表现力。二手的 当将“糖”特征明显而琐碎地翻译成该符号中已经存在的其他结构时。C的a[i]表示法是的语法糖*(a + i) 维基百科文章也有很好的解释。
PetrPudlák13年

3
有趣的内容,但与let的介绍
无关-wirrbel

2
这是一个写得很好的答案,但不能回答原始问题。
约翰·卡尔森

1
@JohanKarlsson我并不是说这是直接答案,但我认为这也与此主题相关。特别是为什么let介绍,因为问题始于我想知道“ let”的起源?
PetrPudlák14年

22

Lisp是现在拥有LET的最古老的语言。但是BASIC是第一个获得它的,因为Lisp后来才获得它。

在Ada Lovelace Analytical Engine(1843)-无LET中,程序看起来像:

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

在Zuse的Plankalkül(1943-45)中,程序看起来如下:

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

短代码由John Mauchly在1949年提出

X3 =  (  X1 +  Y1 )  /  X1 * Y1   

Burks的中级PL,1950年,用于分配 ->

Rutishauser在1952年二手 =>=

Böhms编译器,1952年,使用过 ->

在曼彻斯特大学,阿里克·格兰尼(Alick Glennie)Autocode于1950年代初发展。第一个代码和编译器是1952年为曼彻斯特大学的Mark 1计算机开发的,被认为是第一种编译的高级编程语言。再次,->分配

查尔斯·亚当斯(Charles Adams),Backus小组的FORTRAN 0,布鲁克的自动编码2,鲁宾斯基和卡米宁的ПП1;都是在1954年=

BACAIC(格林斯,波特),1954年,*分配!

1955年,ADES,孔普勒, =

IT,1956年, <-

1957年,FORTRAN, =

AT-3(1956),Math-Matic(1957),再一次=

但在1957年,Flow-Matic进行了两项任务,并且两者都是用语言表达的

TRANSFER a TO bMOVE a TO b

鲍尔和萨梅森的机器,1957年: =>


抱歉,我无法涵盖1957年至1964年之间的所有语言,但涵盖更多语言

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)

还没有LET分配。还是没有,在LISP的情况下。


Dartmouth BASIC是BASIC编程语言的原始版本。第一个交互式版本于19646月提供给普通用户;

 LET / = — assign formula results to a variable

14

好吧,在这三个之间,Lisp肯定是第一个。哈斯克尔是约在上世纪80年代,和Clojure的在00年代,并let一直围绕之前,无论是这些日期的。:-)

关于Lisp是否是发明它语言,我尚不能保证,但是我将做一些研究并看看。:-)

更新:根据《 Lisp的演变》(请参阅第46页),它提到let了70年代发明的:

LET-本身是在每个站点上首先在本地发明和重新发明的宏-后来才进入MacLisp世界;根据Lisp Archive的说法,它是在1979年DEFMACRO与复杂的Lisp Machine DEFUN参数语法同时从Lisp-Machine Lisp追溯吸收到PDP-10 MacLisp中的。

当然,仍然不能完全回答它是否是另一种语言的发明,但这仍然是另一个数据点。:-)


4
ML也是在70年代开发的,因此可能是在那个时期ML和Lisp中都引入了这种想法。
Giorgio

9

1978年1月发布的第一份修订方案报告AIM-452已有LET。第9页

请注意,Lisp之前使用了不同的构造PROG来引入局部变量。

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

本来可以写成大约

(prog (a b)
  (setq a 1)
  (setq b 1)
  (+ a b))

let总词汇用Lisp方言作用域?
wirrbel

1
AIM-452是有关该计划的第一份修订报告。第一份报告是1975年的AIM-349。AIM-848是修订后的修订报告。之后的那个叫做“修订的^ 3”报告(即第一个使用“ R ^ nRS”命名的报告)是第一个不是AIM而是实际语言规范的报告。仔细搜索会发现所有这些文档的PDF,以便您自己阅读。如果想更进一步,可以从软件保护组找到旧的MacLisp手册,也许您也可以找到一些LISP 1.5报告。
TaylanUB 2014年

@wirrbel,它看起来let与词法作用域大约一样古老(Scheme,'75),并且词法作用域需要一段时间才能获得认可,所以我猜想的第一个实例let是在动态作用域Lisps的上下文中。如今,Emacs Lisp默认仍然具有动态作用域,并且lambdalet(无论如何,后者都是前者)动态绑定其参数。
2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.