我已经阅读了维基百科上关于过程式编程和函数式编程的文章,但我还是有点困惑。有人能把它归结为核心吗?
当前回答
过程性语言倾向于跟踪状态(使用变量),并倾向于按步骤序列执行。纯函数式语言不跟踪状态,使用不可变值,并倾向于作为一系列依赖项执行。在许多情况下,调用堆栈的状态所保存的信息与过程代码中存储在状态变量中的信息相同。
递归是函数式编程的一个经典例子。
其他回答
进一步阐述康拉德的评论:
因此,纯函数式程序总是对输入产生相同的值,求值的顺序没有很好的定义;
因此,函数式代码通常更容易并行化。由于函数(通常)没有副作用,并且它们(通常)只是作用于它们的参数,因此许多并发问题都消失了。
当您需要能够证明您的代码是正确的时,也可以使用函数式编程。这在过程式编程中要困难得多(在函数式编程中不容易,但仍然容易)。
免责声明:我已经很多年没有使用函数式编程了,直到最近才开始重新研究它,所以我在这里可能不完全正确。:)
我相信过程式/函数式/目标式编程是关于如何处理问题的。
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.
@Creighton:
在Haskell中有一个叫做product的库函数:
prouduct list = foldr 1 (*) list
或者仅仅是:
product = foldr 1 (*)
惯用语的阶乘
fac n = foldr 1 (*) [1..n]
很简单
fac n = product [1..n]
我在这里没有看到真正强调的一点是,现代函数语言(如Haskell)实际上更多地关注流控制的第一类函数,而不是显式递归。您不需要像上面那样在Haskell中递归地定义阶乘。我想是这样的
fac n = foldr (*) 1 [1..n]
是一个完美的惯用结构,在精神上更接近于使用循环,而不是使用显式递归。
过程性语言倾向于跟踪状态(使用变量),并倾向于按步骤序列执行。纯函数式语言不跟踪状态,使用不可变值,并倾向于作为一系列依赖项执行。在许多情况下,调用堆栈的状态所保存的信息与过程代码中存储在状态变量中的信息相同。
递归是函数式编程的一个经典例子。