我已经阅读了维基百科上关于过程式编程和函数式编程的文章,但我还是有点困惑。有人能把它归结为核心吗?
当前回答
函数式语言(理想情况下)允许您编写一个数学函数,即接受n个参数并返回一个值的函数。如果程序被执行,这个函数将根据需要在逻辑上求值
另一方面,过程式语言执行一系列连续的步骤。(有一种将顺序逻辑转换为函数逻辑的方法,称为连续传递样式。)
因此,纯函数式程序总是对输入产生相同的值,求值的顺序没有很好的定义;这意味着像用户输入或随机值这样的不确定值很难用纯函数式语言建模。
就像这个答案中的其他内容一样,这是一种概括。这个属性,在需要计算结果的时候计算,而不是在调用它的时候按顺序计算,被称为“懒惰”。并不是所有的函数式语言都是懒惰的,懒惰也不仅仅局限于函数式编程。相反,这里给出的描述提供了一个“心理框架”,用于思考不同的编程风格,这些风格不是不同的、相反的类别,而是流动的想法。
其他回答
过程式编程将语句序列和条件构造划分为单独的块,称为过程,这些块通过参数化(非函数式)值。
函数式编程与此类似,只是函数是一类值,因此它们可以作为参数传递给其他函数,并作为函数调用的结果返回。
注意,在这个解释中,函数式编程是过程式编程的泛化。然而,少数人将“函数式编程”解释为没有副作用,这与除Haskell之外的所有主要函数式语言都完全不同,但无关紧要。
这里没有一个答案显示了惯用的函数式编程。递归阶乘的答案很适合在FP中表示递归,但大多数代码不是递归的,所以我不认为这个答案是完全具有代表性的。
假设你有一个字符串数组,每个字符串表示一个整数,比如“5”或“-200”。您希望根据内部测试用例检查这个输入字符串数组(使用整数比较)。两种解决方案如下所示
程序上的
arr_equal(a : [Int], b : [Str]) -> Bool {
if(a.len != b.len) {
return false;
}
bool ret = true;
for( int i = 0; i < a.len /* Optimized with && ret*/; i++ ) {
int a_int = a[i];
int b_int = parseInt(b[i]);
ret &= a_int == b_int;
}
return ret;
}
功能
eq = i, j => i == j # This is usually a built-in
toInt = i => parseInt(i) # Of course, parseInt === toInt here, but this is for visualization
arr_equal(a : [Int], b : [Str]) -> Bool =
zip(a, b.map(toInt)) # Combines into [Int, Int]
.map(eq)
.reduce(true, (i, j) => i && j) # Start with true, and continuously && it with each value
虽然纯函数式语言通常是研究语言(因为现实世界喜欢免费的副作用),但现实世界的过程式语言在适当的时候会使用更简单的函数式语法。
这通常是用Lodash这样的外部库实现的,或者是用Rust这样的新语言内置的。函数式编程的繁重工作是通过map、filter、reduce、currying、partial等函数/概念完成的,最后三个你可以查阅以进一步理解。
齿顶高
In order to be used in the wild, the compiler will normally have to work out how to convert the functional version into the procedural version internally, as function call overhead is too high. Recursive cases such as the factorial shown will use tricks such as tail call to remove O(n) memory usage. The fact that there are no side effects allows functional compilers to implement the && ret optimization even when the .reduce is done last. Using Lodash in JS, obviously does not allow for any optimization, so it is a hit to performance (Which isn't usually a concern with web development). Languages like Rust will optimize internally (And have functions such as try_fold to assist && ret optimization).
在计算机科学中,函数式编程是一种编程范式,它将计算视为数学函数的求值,并避免状态和可变数据。它强调函数的应用,与强调状态变化的过程式编程风格相反。
Funtional编程
num = 1
def function_to_add_one(num):
num += 1
return num
function_to_add_one(num)
function_to_add_one(num)
function_to_add_one(num)
function_to_add_one(num)
function_to_add_one(num)
#Final Output: 2
过程式编程
num = 1
def procedure_to_add_one():
global num
num += 1
return num
procedure_to_add_one()
procedure_to_add_one()
procedure_to_add_one()
procedure_to_add_one()
procedure_to_add_one()
#Final Output: 6
Function_to_add_one是一个函数
Procedure_to_add_one是一个过程
即使你运行这个函数5次,每次它都会返回2
如果你运行这个过程五次,在第五次运行结束时,它会给你6。
免责声明:显然,这是对现实的一种超简化的看法。这个答案只是让我们了解了“函数”而不是“过程”。仅此而已。一旦你尝到了这种肤浅而深刻的直觉,开始探索这两种范式,你就会开始清楚地看到它们的区别。
对我的学生有帮助,希望对你们也有帮助。
函数式编程与不使用全局变量的过程式编程相同。
推荐文章
- 面向对象编程,函数式编程,过程式编程
- 什么是面向方面编程?
- 为什么不可变性在JavaScript中如此重要(或需要)?
- 如何使用underscore.js作为模板引擎?
- 降价vs加价——它们有关联吗?
- Scala中的“提升”是什么?
- Javascript相当于Python的zip函数
- 使用array_map()访问第一级键,而不调用' array_keys() '
- functools partial是怎么做的呢?
- 过程式编程和函数式编程的区别是什么?
- 没有可变状态,你怎么能做任何有用的事情?
- 如何在Python中使用lambda排序
- 什么是参考透明度?
- 为什么Python不适合函数式编程?
- 滥用代数数据类型的代数——为什么会这样?