我一直在网上搜索声明式编程和命令式编程的定义,希望能给我一些启发。然而,我发现在一些资源中使用的语言令人生畏——例如在维基百科。 有没有人可以给我举一个现实世界的例子,让我对这个主题有一些了解(也许是c#)?


当前回答

这种差异主要与抽象的总体水平有关。对于声明式,在某些情况下,您离单个步骤太远了,以至于程序在如何获得结果方面有很大的自由度。


你可以把每一条指令都看作是连续体上的某个地方:

抽象程度:

Declarative <<=====|==================>> Imperative

声明性真实世界的例子:

图书管理员,请帮我借一本《白鲸记》。 (图书管理员可酌情选择最佳的申请方式)

现实世界的例子:

进入图书馆 查找图书组织系统(卡片目录-老派) 研究如何使用卡片目录(你也忘了,对吧) 弄清楚货架是如何标记和组织的。 弄清楚书架上的书是如何排列的。 从卡片目录和组织系统中交叉引用图书位置以查找所述书籍。 带书到退房系统。 借书。

其他回答

我只是想知道为什么没有人提到Attribute类是c#中的声明性编程工具。本页最流行的回答是将LINQ作为一种声明性编程工具。

根据维基百科

常见的声明性语言包括数据库查询语言 (如SQL, XQuery),正则表达式,逻辑编程, 功能编程和配置管理系统。

所以LINQ作为一个函数式语法,绝对是一个声明性的方法,但是c#中的Attribute类作为一个配置工具,也是声明性的。这里有一个很好的起点来阅读更多关于它的内容:c#属性编程的快速概述

声明性程序只是它的一些或多或少的“通用”命令式实现/虚拟机的数据。

pluses: specifying just a data, in some hardcoded (and checked) format, is simpler and less error-prone than specifying variant of some imperative algorithm directly. some complex specifications just cant be written directly, only in some DSL form. best and freq used in DSLs data structures is sets and tables. because you not have dependencies between elements/rows. and when you havent dependencies you have freedom to modify and ease of support. (compare for example modules with classes - with modules you happy and with classes you have fragile base class problem) all goods of declarativeness and DSL follows immediately from benefits of that data structures (tables and sets). another plus - you can change implementation of declarative language vm, if DSL is more-or-less abstract (well designed). make parallel implementation, for example. or port it to other os etc. all good specifed modular isolating interfaces or protocols gives you such freedom and easyness of support.

缺点: 你猜对了。一般的(通过DSL参数化的)命令式算法/虚拟机实现可能比特定的算法慢和/或占用内存。在某些情况下。 如果这种情况很罕见,那就忘了它吧,让它慢慢来。如果这种情况经常发生,你总是可以扩展你的DSL/vm。某个能减缓其他案件的地方,当然…

P.S.框架介于DSL和命令式之间。作为所有的折中方案……他们结合了缺点,而不是优点。它们不是那么安全,也不是那么快:)看看万事通haskell——它介于强大的简单ML和灵活的元程序Prolog之间……真是个怪物。你可以把Prolog看作一个Haskell,它只包含布尔函数/谓词。它对Haskell的灵活性是多么简单……

命令式编程 一种需要编程规程的编程语言,如C/ c++, Java, COBOL, FORTRAN, Perl和JavaScript。用这种语言编写程序的程序员必须基于数据处理和编程知识,开发出适当的操作顺序来解决问题。

声明性编程 一种不需要编写传统编程逻辑的计算机语言; 用户专注于定义输入和输出,而不是过程式编程语言(如c++或Java)中所需的程序步骤。

声明性编程的例子有CSS、HTML、XML、XSLT、RegX。

已经添加了很多代码示例,所以我不再添加另一个。 相反,我将尝试用一种我认为比大多数流行的定义更清楚地解释这两种方法之间的区别:

声明性方法侧重于特定算法的目的,这通常隐藏了算法本身。 命令式方法侧重于特定目的的算法,通常隐藏了目的本身。

这里借用菲利普·罗伯茨的一句话:

命令式编程告诉机器如何做某事(导致你想要发生的事情) 声明性编程告诉机器你想要发生什么(然后计算机找出如何去做)

两个例子:

1. 将数组中的所有数字加倍

命令式地:

var numbers = [1,2,3,4,5]
var doubled = []

for(var i = 0; i < numbers.length; i++) {
  var newNumber = numbers[i] * 2
  doubled.push(newNumber)
}
console.log(doubled) //=> [2,4,6,8,10]

声明:

var numbers = [1,2,3,4,5]

var doubled = numbers.map(function(n) {
  return n * 2
})
console.log(doubled) //=> [2,4,6,8,10]

2. 对列表中的所有项求和

命令式地

var numbers = [1,2,3,4,5]
var total = 0

for(var i = 0; i < numbers.length; i++) {
  total += numbers[i]
}
console.log(total) //=> 15

以声明的方式

var numbers = [1,2,3,4,5]

var total = numbers.reduce(function(sum, n) {
  return sum + n
});
console.log(total) //=> 15

请注意,命令式示例涉及如何创建一个新变量,改变它,并返回新值(即,如何使某事发生),而声明式示例执行给定的输入,并根据初始输入返回新值(即,我们想要发生什么)。