我已经阅读了维基百科上关于过程式编程和函数式编程的文章,但我还是有点困惑。有人能把它归结为核心吗?
当前回答
在计算机科学中,函数式编程是一种编程范式,它将计算视为数学函数的求值,并避免状态和可变数据。它强调函数的应用,与强调状态变化的过程式编程风格相反。
其他回答
要理解其中的区别,需要理解过程式编程和函数式编程的“教父”范式都是命令式编程。
基本上,过程式编程只是构造命令式程序的一种方式,其中主要的抽象方法是“过程”。(或某些编程语言中的“函数”)。甚至面向对象编程也只是构造命令式程序的另一种方式,其中状态被封装在对象中,成为一个具有“当前状态”的对象,加上这个对象有一组函数、方法和其他东西,可以让程序员操作或更新状态。
现在,关于函数式编程,其方法的要点是它确定要取什么值,以及应该如何传递这些值。(因此没有状态,也没有可变数据,因为它将函数作为第一类值,并将它们作为参数传递给其他函数)。
PS:理解所使用的每一种编程范式应该能澄清它们之间的差异。
PSS:归根结底,编程范式只是解决问题的不同方法。
PSS: quora上的这个答案有一个很好的解释。
函数式语言(理想情况下)允许您编写一个数学函数,即接受n个参数并返回一个值的函数。如果程序被执行,这个函数将根据需要在逻辑上求值
另一方面,过程式语言执行一系列连续的步骤。(有一种将顺序逻辑转换为函数逻辑的方法,称为连续传递样式。)
因此,纯函数式程序总是对输入产生相同的值,求值的顺序没有很好的定义;这意味着像用户输入或随机值这样的不确定值很难用纯函数式语言建模。
就像这个答案中的其他内容一样,这是一种概括。这个属性,在需要计算结果的时候计算,而不是在调用它的时候按顺序计算,被称为“懒惰”。并不是所有的函数式语言都是懒惰的,懒惰也不仅仅局限于函数式编程。相反,这里给出的描述提供了一个“心理框架”,用于思考不同的编程风格,这些风格不是不同的、相反的类别,而是流动的想法。
进一步阐述康拉德的评论:
因此,纯函数式程序总是对输入产生相同的值,求值的顺序没有很好的定义;
因此,函数式代码通常更容易并行化。由于函数(通常)没有副作用,并且它们(通常)只是作用于它们的参数,因此许多并发问题都消失了。
当您需要能够证明您的代码是正确的时,也可以使用函数式编程。这在过程式编程中要困难得多(在函数式编程中不容易,但仍然容易)。
免责声明:我已经很多年没有使用函数式编程了,直到最近才开始重新研究它,所以我在这里可能不完全正确。:)
我相信过程式/函数式/目标式编程是关于如何处理问题的。
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.
康拉德说:
因此,纯函数式程序总是为输入产生相同的值, 评价的顺序也不明确;这意味着不确定的值,比如 用户输入或随机值很难用纯函数式语言建模。
在一个纯函数式程序中求值的顺序可能很难(或者)解释(尤其是懒惰的人),甚至不重要,但我认为说它没有被很好地定义,听起来就像你根本无法判断你的程序是否会工作!
Perhaps a better explanation would be that control flow in functional programs is based on when the value of a function's arguments are needed. The Good Thing about this that in well written programs, state becomes explicit: each function lists its inputs as parameters instead of arbitrarily munging global state. So on some level, it is easier to reason about order of evaluation with respect to one function at a time. Each function can ignore the rest of the universe and focus on what it needs to do. When combined, functions are guaranteed to work the same[1] as they would in isolation.
... 像用户输入或随机值这样的不确定值很难纯粹地建模 函数式语言。
The solution to the input problem in purely functional programs is to embed an imperative language as a DSL using a sufficiently powerful abstraction. In imperative (or non-pure functional) languages this is not needed because you can "cheat" and pass state implicitly and order of evaluation is explicit (whether you like it or not). Because of this "cheating" and forced evaluation of all parameters to every function, in imperative languages 1) you lose the ability to create your own control flow mechanisms (without macros), 2) code isn't inherently thread safe and/or parallelizable by default, 3) and implementing something like undo (time travel) takes careful work (imperative programmer must store a recipe for getting the old value(s) back!), whereas pure functional programming buys you all these things—and a few more I may have forgotten—"for free".
我希望这听起来不像狂热,我只是想补充一些观点。命令式编程,特别是像c# 3.0这样的强大语言中的混合范式编程,仍然是完成工作的完全有效的方法,并且没有银弹。
[1]…除了内存使用方面(参考Haskell中的foldl和foldl')。