我已经阅读了维基百科上关于过程式编程和函数式编程的文章,但我还是有点困惑。有人能把它归结为核心吗?


当前回答

如果你有机会,我建议你买一份Lisp/Scheme,然后用它来做一些项目。最近流行起来的大多数思想都是在几十年前用Lisp表达的:函数式编程、延续(作为闭包)、垃圾收集,甚至XML。

所以这将是一个很好的方法来开始所有这些当前的想法,以及一些其他的,比如符号计算。

您应该知道函数式编程擅长什么,不擅长什么。它并不是什么都好。有些问题最好用副作用来表达,同样的问题会根据提问的时间给出不同的答案。

其他回答

在计算机科学中,函数式编程是一种编程范式,它将计算视为数学函数的求值,并避免状态和可变数据。它强调函数的应用,与强调状态变化的过程式编程风格相反。

函数式语言(理想情况下)允许您编写一个数学函数,即接受n个参数并返回一个值的函数。如果程序被执行,这个函数将根据需要在逻辑上求值

另一方面,过程式语言执行一系列连续的步骤。(有一种将顺序逻辑转换为函数逻辑的方法,称为连续传递样式。)

因此,纯函数式程序总是对输入产生相同的值,求值的顺序没有很好的定义;这意味着像用户输入或随机值这样的不确定值很难用纯函数式语言建模。


就像这个答案中的其他内容一样,这是一种概括。这个属性,在需要计算结果的时候计算,而不是在调用它的时候按顺序计算,被称为“懒惰”。并不是所有的函数式语言都是懒惰的,懒惰也不仅仅局限于函数式编程。相反,这里给出的描述提供了一个“心理框架”,用于思考不同的编程风格,这些风格不是不同的、相反的类别,而是流动的想法。

进一步阐述康拉德的评论:

因此,纯函数式程序总是对输入产生相同的值,求值的顺序没有很好的定义;

因此,函数式代码通常更容易并行化。由于函数(通常)没有副作用,并且它们(通常)只是作用于它们的参数,因此许多并发问题都消失了。

当您需要能够证明您的代码是正确的时,也可以使用函数式编程。这在过程式编程中要困难得多(在函数式编程中不容易,但仍然容易)。

免责声明:我已经很多年没有使用函数式编程了,直到最近才开始重新研究它,所以我在这里可能不完全正确。:)

我从来没有在其他地方看到过这样的定义,但我认为这很好地总结了这里给出的差异:

函数式编程主要关注表达式

过程式编程主要关注语句

表达式有值。函数式程序是一个表达式,其值是由计算机执行的一系列指令。

语句没有值,而是修改一些概念机器的状态。

在纯函数式语言中,没有语句,也就是说没有办法操纵状态(它们可能仍然有一个名为“语句”的语法结构,但除非它操纵状态,否则我不会在这种意义上称其为语句)。在纯程序语言中,没有表达式,一切都是操纵机器状态的指令。

Haskell是纯函数式语言的一个例子,因为没有办法操纵状态。机器代码是纯过程语言的一个例子,因为程序中的所有内容都是操作机器寄存器和内存状态的语句。

令人困惑的部分是,绝大多数编程语言同时包含表达式和语句,允许您混合使用范式。语言可以根据它们鼓励使用语句和表达式的程度被分类为更函数化或更过程化。

For example, C would be more functional than COBOL because a function call is an expression, whereas calling a sub program in COBOL is a statement (that manipulates the state of shared variables and doesn't return a value). Python would be more functional than C because it allows you to express conditional logic as an expression using short circuit evaluation (test && path1 || path2 as opposed to if statements). Scheme would be more functional than Python because everything in scheme is an expression.

你仍然可以在一种鼓励过程范式的语言中以函数式风格编写,反之亦然。只是在语言不鼓励的范式下写作更困难和/或更尴尬。

我相信过程式/函数式/目标式编程是关于如何处理问题的。

The first style would plan everything in to steps, and solves the problem by implementing one step (a procedure) at a time. On the other hand, functional programming would emphasize the divide-and-conquer approach, where the problem is divided into sub-problem, then each sub-problem is solved (creating a function to solve that sub problem) and the results are combined to create the answer for the whole problem. Lastly, Objective programming would mimic the real world by create a mini-world inside the computer with many objects, each of which has a (somewhat) unique characteristics, and interacts with others. From those interactions the result would emerge.

每种编程风格都有自己的优点和缺点。因此,做一些诸如“纯编程”(即纯粹的程序设计——顺便说一下,没有人会这样做,这有点奇怪——或纯粹的函数式或纯粹的目标)是非常困难的,如果不是不可能的话,除了一些专门设计来展示编程风格优势的基本问题(因此,我们称那些喜欢纯粹的人为“weenie”:D)。

Then, from those styles, we have programming languages that is designed to optimized for some each style. For example, Assembly is all about procedural. Okay, most early languages are procedural, not only Asm, like C, Pascal, (and Fortran, I heard). Then, we have all famous Java in objective school (Actually, Java and C# is also in a class called "money-oriented," but that is subject for another discussion). Also objective is Smalltalk. In functional school, we would have "nearly functional" (some considered them to be impure) Lisp family and ML family and many "purely functional" Haskell, Erlang, etc. By the way, there are many general languages such as Perl, Python, Ruby.