关于强制式(命令式)语言和声明式语言的区别
在阅读Alfred V.Aho等的大作Compilers Principles,Techniques and Tools是看到如下一段话:
Another classification of languages uses the term imperative for languages in which a program specifies how a computation is to be done and declarative for languages in which a program specifies what computation is to be done. Languages such as C, C++, C#, and Java are imperative languages . In imperative languages there is a notion of program state and statements that change the state. Functional languages such as ML and Haskell and constraint logic languages such as Prolog are often considered to be declarative languages.
讲到的是强制式语言(imperative languages,部分国内学者译为命令式语言、指令式语言)和声明式语言(declarative languages),同时还提到了函数式语言(Functional languages)和约束逻辑式语言(constraint logic languages)的概念。关于后两者如果有时间会在以后和大家进行探讨,今天暂时先说明一下前两者。
命令式编程(Imperative programming),即利用命令式语言进行编程的方式,是一种描述计算机所需作出的行为的编程范型。命令式编程语言使用变量和更复杂的语句,但仍依从相同的范型。食谱和行动清单,虽非计算机程序,但与命令式编程有相似的风格:每步都是指令,有形地控制世界情况。因为命令式编程的基础观念,不但概念上比较熟悉,而且较容易具体表现于硬件,所以大部分的编程语言都是指令式的。如上述的C, C++, C# 和 Java。大部分的命令式高级编程语言都支持四种基本的语句:运算语句、循环语句、条件分支语句、无条件分支语句。
运算语句一般来说都表现了在存储器内的数据进行运算的行为,然后将结果存入存储器中以便日后使用。高级命令式编程语言更能处理复杂的表达式,可能会产生四则运算和函数计算的结合。其中循环、条件分支和无条件分支都是控制流程。
循环语句容许一些语句反复运行数次。循环可依据一个默认的数目来决定运行这些语句的次数;或反复运行它们,直至某些条件改变。
条件分支语句容许仅当某些条件成立时才运行某个区块。否则,这个区块中的语句会略去,然后按区块后的语句继续运行。
无条件分支语句容许运行顺序转移到程序的其他部分之中。包括跳跃(在很多语言中称为Goto)、副程序和Procedure等。
早期的命令式编程语言都是计算机本身的机械语言。在这些语言中,指示非常简单,令硬件的运行更容易,却阻碍了复杂程序的设计。1954年开始开发的FORTRAN,是首个在复杂程序的设计中除掉机器码的编程语言。它是编译型的编程语言,容许命名变量、复杂的表达式、副程序和其他功能,这些功能现在在指令式语言中都非常普遍。后来的二十年中,可以看到大量的其他高级命令式编程语言出现。在1980年后,面向对象编程有迅速的发展;面向对象编程语言均有着指令式的风格,但增添了支持对象的功能。
声明式编程(Declarative programming),即利用声明式语言进行编程的方式,与命令式编程相对立。它描述目标性质,让计算机明白目标,而非流程。声明式编程不用告诉计算机问题领域,从而避免随之而来的副作用。而指令式编程则需要用算法来明确的指出每一步该怎么做。它通常被看做是形式逻辑的理论,把计算看做推导。声明式编程因大幅简化了并行计算的编写难度,自2009起备受关注。声明式语言包括数据库查询语言(SQL,XQuery),正则表达式,逻辑编程,函数式编程和组态管理系统。这种编程方式通过函数、推论规则或项重写(term-rewriting)规则,来描述变量之间的关系。它的语言运行器(编译器或解释器)采用了一个固定的算法,以从这些关系产生结果。目前,声明式编程语言通常用作解决人工智能和约束满足问题。