函数式编程、声明式编程和命令式编程是什么意思?


当前回答

简而言之,一种编程风格越是强调“做什么”(What (to do))而忽略了“如何做”(How (to do))的细节,这种风格就越被认为是声明性的。而imperative则相反。函数式编程与声明式风格相关联。

其他回答

命令式编程:告诉“机器”如何做某事,结果你想发生的事情就会发生。

声明式编程:告诉“机器”你想要发生什么,然后让计算机想出如何去做。

命令式的例子

function makeWidget(options) {
    const element = document.createElement('div');
    element.style.backgroundColor = options.bgColor;
    element.style.width = options.width;
    element.style.height = options.height;
    element.textContent = options.txt;

    return element;
}

声明性的例子

function makeWidget(type, txt) {
    return new Element(type, txt);
}

注:区别不在于简洁、复杂或抽象。如前所述,区别在于如何做和做什么。

现在,新的焦点是:我们需要旧的分类吗?

命令式/声明式/函数式在过去很好地分类了泛型语言,但是现在所有的“大语言”(如Java、Python、Javascript等)都有一些选项(通常是框架)来表达其主要关注点(通常是命令式)之外的“其他关注点”,并表达并行进程、声明式函数、lambdas等。

所以这个问题的一个很好的变体是“今天对框架进行分类的优点是什么?” ... 一个重要的方面是我们可以标记为“编程风格”……

重点研究数据与算法的融合

这是一个很好的例子。你可以在维基百科上读到jQuery,

jQuery的一系列核心特性——DOM元素选择、遍历和操作——由它的选择器引擎(…)支持,创建了一种新的“编程风格”,融合了算法和DOM数据结构

因此jQuery是关注“新编程风格”的最佳(流行)例子,它不仅是面向对象的,而且是“融合算法和数据结构”。jQuery有点像电子表格,但不是“面向单元格”,是“面向dom节点”…比较本文中的主要风格:

No fusion: in all "big languages", in any Functional/Declarative/Imperative expression, the usual is "no fusion" of data and algorithm, except by some object-orientation, that is a fusion in strict algebric structure point of view. Some fusion: all classic strategies of fusion, in nowadays have some framework using it as paradigm... dataflow, Event-driven programming (or old domain specific languages as awk and XSLT)... Like programming with modern spreadsheets, they are also examples of reactive programming style. Big fusion: is "the jQuery style"... jQuery is a domain specific language focusing on "fusing algorithms and DOM-data-structures". PS: other "query languages", as XQuery, SQL (with PL as imperative expression option) are also data-algorith-fusion examples, but they are islands, with no fusion with other system modules... Spring, when using find()-variants and Specification clauses, is another good fusion example.

命令式和声明式描述了两种相反的编程风格。命令式是传统的“循序渐进”方法,而声明式则更多地是“这就是我想要的,现在你来研究如何去做”。

这两种方法贯穿于整个编程过程——即使使用相同的语言和相同的程序。一般来说,声明式方法被认为是更可取的,因为它使程序员不必指定如此多的细节,同时也减少了出现错误的机会(如果您描述了您想要的结果,并且一些经过良好测试的自动流程可以从该结果向后工作以定义步骤,那么您可能希望事情比手工指定每个步骤更可靠)。

另一方面,命令式方法为您提供了更多的低级控制——这是编程的“微观管理方法”。这可以让程序员利用有关问题的知识来给出更有效的答案。因此,程序的某些部分以声明式的风格编写并不罕见,但对速度至关重要的部分则更加必要。

as you might imagine, the language you use to write a program affects how declarative you can be - a language that has built-in "smarts" for working out what to do given a description of the result is going to allow a much more declarative approach than one where the programmer needs to first add that kind of intelligence with imperative code before being able to build a more declarative layer on top. so, for example, a language like prolog is considered very declarative because it has, built-in, a process that searches for answers.

so far, you'll notice that i haven't mentioned functional programming. that's because it's a term whose meaning isn't immediately related to the other two. at its most simple, functional programming means that you use functions. in particular, that you use a language that supports functions as "first class values" - that means that not only can you write functions, but you can write functions that write functions (that write functions that...), and pass functions to functions. in short - that functions are as flexible and common as things like strings and numbers.

it might seem odd, then, that functional, imperative and declarative are often mentioned together. the reason for this is a consequence of taking the idea of functional programming "to the extreme". a function, in it's purest sense, is something from maths - a kind of "black box" that takes some input and always gives the same output. and that kind of behaviour doesn't require storing changing variables. so if you design a programming language whose aim is to implement a very pure, mathematically influenced idea of functional programming, you end up rejecting, largely, the idea of values that can change (in a certain, limited, technical sense).

如果你这样做——如果你限制变量的改变方式——那么你几乎会意外地迫使程序员编写更具声明性的程序,因为命令式编程的很大一部分是描述变量如何改变,而你再也不能这样做了!因此,函数式编程——特别是用函数式语言编程——倾向于给出更多的声明性代码。

总结一下:

命令式和声明式是两种相反的编程风格(鼓励这些风格的编程语言使用相同的名称) 函数式编程是一种编程风格,其中函数变得非常重要,因此,更改值变得不那么重要。在值中指定更改的有限能力迫使使用更声明性的风格。

因此,“函数式编程”通常被描述为“声明式的”。

命令式——表达式描述要执行的动作序列(关联的)

声明性——表达式是对程序行为做出贡献的声明(关联、交换、幂等、单调)

函数式表达式的值仅为效果;语义支持等式推理

这里有一些关于所提到的“类型”的好答案。

我还提供了一些额外的、更“奇特”的概念,通常与函数式编程人群有关:

领域特定语言或DSL编程:创建一种新的语言来处理手头的问题。 元编程:当你的程序编写其他程序时。 进化编程:你构建一个系统,它可以不断地自我改进,或者不断地生成更好的子程序。