首页 » IT » 程序设计语言

程序设计语言

Fortran - 最古老的高级程序设计语言,它提供强大的方法来表达数学公式(Fortran的意思是Formula translation,公式翻译)。

Algol。来自鱼书11章引言的脚注:Algol-68是一种庞大的语言,它基于一种小巧而有效的语言Algol-60。Algol-68难以理解、难以实现、难以使用,但几乎每个人都认为它“非常强大”。Algol-68取代了Algol-60,成功地使后者销声匿迹。但由于其使用不便,Algol-68也很快退出了历史舞台。

Clu - MIT开发的一种实验性语言,它的关键思想是Cluster - 集群。

语法糖(Syntactic sugar) - 为方便程序员使用而设计的语法,不涉及语言本质的东西。

C/C++

在UNIX的早期,KenThompson为UNIX开发了B语言,但缺乏类型,Dennis Ritchie改进了B语言,新的语言叫C(1972)。80年代,Bjarne Stroustrup为C添加了类,亦即面向对象的功能,并将新语言叫做 C With Class(1979),后来征集名字,并重命名为C++(1983)。

在C/C++的历史上,有几个主要的开创者与推进者,首先是Ken Thompson和Dennis Ritchie,前者开发了UNIX,后者开发了C,当然UNIX和C相互影响、共同演化,就如两位开创者一样,作为最好的同事和朋友,他们在1983年共获图灵奖。

原本C++的目的是要取代C,但现在看如果不是绝无可能,那也是遥遥无期了。2000年后,由于Java、C#等的挤压,以及如Python, Ruby等动态语言的兴起,以及Apple东山再起后带动Object-C,C++江河日下。内存管理的噩梦、标准库的进展缓慢、复杂的语法、线程库/GUI库的缺失等等,都让C++逐渐失去民心。多少人怀抱梦想靠近C++,却又多少次被击退。但情况也没这么悲观,标准化进程还在推进,随着云计算的规模化运作,软件性能以及能耗得到更多的重视,移动设备/嵌入式应用越来越多,C++还是有一定的用武之地。

C/C++领域的经典书非常多,比较知名的有《C程序设计语言》、《C++程序设计语言》、《C专家编程》(鱼书)、《C与指针》、《C陷阱与缺陷》、《C++沉思录》、《C++ Primer》、《C++对象模型》、《C++设计与演化》。如果把UNIX算在其中,还应当包括《UNIX环境编程》、《UNIX网络编程》、《Unix编程艺术》等。

C标准有C89, C99, C1X(目前看是C11)。C++标准有C++ 98,C++ 2004(相对于C++ 98只有较少的变动),C++ 1x(流传很久的C++0x最终没有在09年实现,升级到C++ 1x)。自90年代后,C++标准把主要精力放在模版(template)上,诞生了著名的STL(标准模版库)和Boost库。

Python

Python的设计者Guido van Rossum(现就职于Google),被称为善意的独裁者。Python最早的版本于1991年发布。有关Python的设计原则,The Zen of Python写道:

There should be one -- and preferably only one -- obvious way to do it. Although that way may not be obvious at first unless you're Dutch.

“除非你是荷兰人!”这是对Guido van Rossum善意的玩笑 ;-)

Lisp

LISP - LISP(LISt Processor),列表处理器。由John McCarthy在1960年左右创造的一种基于λ演算的函数式编程语言。LISP有许多变种。

  • Common Lisp - 1980年代Guy L. Steele编写。
  • Scheme - 1970年代由MIT的Guy Lewis Steele Jr.、Gerald Jay Sussman创建。
  • Emacs Lisp - Emacs中使用的Lisp方言。
  • Clojure - 新兴的LISP方言。

学习Common Lisp的几本经典著作:Paul Graham的On Lisp(网上有中译PDF)、ANSI Common Lisp,Guy L. Steele Jr.的Common Lisp: the Language(昵称为CLTL),Peter Seibel的Practical Common Lisp(《实用Common Lisp编程》)。

以下关于Lisp的笔记,主要摘抄自徐宥的文章:编程珠玑番外篇 -K. 高级语言是怎么来的-7 - LISP 语言前传

Lisp历史从IBM的704机器说起。1946年ENIAC出现,1954年IBM 704发布,可进行浮点计算、面向科学和工程的计算机。世界上最早的语音合成程序是Bell实验室的科学家在704上完成,Fortran、Lisp最早也在704上实现。1957年,IBM决定捐献1台704给MIT。当时Dartmouth教书的John McCarthy和在MIT教书的Marvin Minsky关系不错,因此有机会玩弄704。当时部署计算机的周期很长,而Minsky手里有一个IBM的项目:用计算机证明平面几何问题。因为机子没有部署完成,他们只好从抽象层面思考解决问题的方案。其思考的结果,是开发一套支持符号计算的Fortran子系统,用一系列的Fortran子程序来做逻辑推理和符号演绎。

704部署完成后,McCarthy带着2个研究生将之前思考的程序实现了,并命名为FLPL(Fortran列表处理语言)。然因Fortran语言本身的限制,McCarthy在写自动求函数导数的程序时,发现FLPL的2大弱点:递归和IF语句。704上的Fortran不支持递归,而递归又非常依赖IF语句。早期Fortran的IF语法是:

IF (expr) A B C

翻译成伪代码可理解为:

if expr < 0: goto A
if expr == 0: goto B
if expr > 0: goto C

704 Fortran的IF隐藏了3个Goto,饱受诟病,Fortran 77开始支持结构化的IF,Fortran 90进一步宣布三分支跳转的用法已过时不再支持。再回头说McCarthy的问题,在FLPL中他用一个名为XIF的子程序完成类似IF的分支(结构化程序中的IF)功能:

XIF (condition, exprA, exprB)

McCarthy很快发现XIF的语义并不正确,因为在Fortran和其他高级语言中,函数参数的值在进入函数前必须全部确定,而作为函数的XIF的参数exprA/exprB不论走到那个分支,都会被计算,因此用函数实现IF是不正确的。

以下作者列举了一个有趣的例子,关于C++函数重载,虽与Lisp无关,但很有意思:

C语言的逻辑与(&&)和逻辑或(||)隶属于短路表达式,即 A && B 这个表达式,若A为false,则无需计算B的值,即B的计算被“短路”,同样 A || B 这个表达式,若A为true,则无需计算B的值。C++允许重载 &&,因此程序员可以实现对象的逻辑与运算,如 objA && objB,然而 objA.operator&&(objB) 并不等价于 A && B,缘故是 objA.operator&&() 是个函数,在求值前需要先计算objB的值,但后者是个短路表达式,不一定需要对objB求值,因此从语义上说,两者并不等价。

递归和IF的问题,让McCarthy希望抛开Fortran,设计一个新语言。此时McCarthy正好跳槽到MIT做助理教授,而MIT有足够多的变成强人帮助McCarthy完成这个新语言的设计实现,这个强人就是Steve Russell,而这个新语言就是Lisp。

以下笔记来自徐宥的编程珠玑番外篇 -J. 高级语言是怎么来的-6 - SCHEME 语言是怎么来的 -1

Scheme是Lisp的一个方言(dialect),SICP一书以Scheme为教学语言(SICP的作者就是Scheme的作者)。Paul Graham用Common Lisp写的Viaweb在1998年以近5000w$的价格卖给Yahoo!,并凭借这个买卖的收益经营Y Combinator天使投资;ITA(被Google收购)担负着世界上大部分的航班咨询查询,核心系统也是Common Lisp。

函数作为一级对象。函数作为参数,典型的如apply、map和reduce。如apply的一个例子:apply(add,(1,2)),即把列表(1,2)作为参数,传给第一个参数(函数add)求值,结果为3。

自由变量。对函数求值不可缺少的变量成为必要变量,如(+ x y)中,x和y都是必要变量。“输入参数一样,输出结果必然一样”这个结论不总是成立,如C语言的time()/rand()函数。在函数的必要变量中,不是函数的输入参数或内部变量的变量(受限变量 bounded variable),称为自由变量(free variable)。如C中的全局变量可视之为自由变量。

定义一个做加n的函数,以及基于此定义一个加1的函数:

(define (addn s) (lambda x (+ x s)))
(define (add1 s) ((addn 1) s))

addn:输入一个s,输出一个函数,对任意x返回x+s。(addn 1)返回一个函数,对输入s计算(+ 1 s)。在Scheme之前的Lisp解析器计算(add1 4)可能返回8,而不是我们期望的5。

参考

Bjarne Stroustrup的《C++的设计与演化》、松本行弘的《松本行弘的程序世界》等书,有作为程序语言设计者的思考。 徐宥的《编程珠玑番外篇 高级语言是怎么来的》系列文章对编程语言有广泛而深入的讨论。

一些程序语言的学习笔记:C/C++Python

分享

0