介绍
函数式编程是一种编程范式,我们尝试在其中以纯数学函数风格绑定所有内容。它是一种声明式的编程风格。它的主要重点是“要解决什么”,而命令式风格则主要关注“如何解决”。它使用表达式而不是语句。对表达式求值以产生值,而执行语句以分配变量。这些函数具有以下讨论的一些特殊功能。
函数式编程基于 Lambda 演算:
Lambda 演算是由 Alonzo Church 开发的用于研究函数计算的框架。它可以称为世界上最小的编程语言。它给出了可计算的定义。任何可以通过 lambda 演算计算的东西都是可计算的。它的计算能力相当于图灵机。它为描述功能及其评估提供了理论框架。它构成了几乎所有当前函数式编程语言的基础。
事实:Alan Turing 是 Alonzo Church 的学生,他创造了图灵机,为命令式编程风格奠定了基础。
支持函数式编程的编程语言: Haskell、JavaScript、 Python、Scala、Erlang、Lisp、ML、Clojure、OCaml、Common Lisp、Racket。
函数式编程的概念:
- 纯函数
- 递归
- 参照透明度
- 函数是一流的,可以是高阶的
- 变量是不可变的
纯函数:这些函数有两个主要属性。首先,它们总是为相同的参数产生相同的输出,而不管其他任何事情。
其次,它们没有副作用,即它们会修改任何参数或全局变量或输出一些东西。
后来的属性称为不变性。纯函数的唯一结果是它返回的值。它们是确定性的。
使用函数式编程完成的程序易于调试,因为纯函数没有副作用或隐藏的 I/O。纯函数还可以更轻松地编写并行/并发应用程序。当以这种风格编写代码时,智能编译器可以做很多事情——它可以并行化指令,在需要时等待评估结果,并记住结果,因为只要输入不变,结果就永远不会改变。
纯函数的例子:
sum(x, y) // sum is function taking x and y as arguments
return x + y // sum is returning sum of x and y without changing them
递归:函数式语言中没有“for”或“while”循环。函数式语言中的迭代是通过递归实现的。递归函数反复调用自己,直到达到基本情况。
递归函数的例子:
fib(n)
if (n <= 1)
return 1;
else
return fib(n - 1) + fib(n - 2);
引用透明:在函数式程序中,变量一旦定义就不会在整个程序中改变它们的值。函数式程序没有赋值语句。如果我们必须存储一些值,我们会定义新的变量。这消除了任何副作用的可能性,因为任何变量都可以在任何执行点替换为其实际值。任何变量的状态在任何时刻都是恒定的。
例子:
x = x + 1 // this changes the value assigned to the variable x.
// So the expression is not referentially transparent.
函数是一等的并且可以是高阶的:一等函数被视为一等变量。第一类变量可以作为参数传递给函数,可以从函数返回或存储在数据结构中。高阶函数是将其他函数作为参数的函数,它们也可以返回函数。
例子:
show_output(f) // function show_output is declared taking argument f
// which are another function
f(); // calling passed function
print_gfg() // declaring another function
print("hello gfg");
show_output(print_gfg) // passing function in another function
变量是不可变的:在函数式编程中,我们不能在变量初始化后修改它。我们可以创建新变量——但我们不能修改现有变量,这确实有助于在整个程序运行时维护状态。一旦我们创建了一个变量并设置了它的值,我们就可以完全确信该变量的值永远不会改变。
函数式编程的优缺点
优点:
- 纯函数更容易理解,因为它们不改变任何状态,只依赖于给它们的输入。他们产生的任何输出都是他们给出的返回值。它们的函数签名给出了关于它们的所有信息,即它们的返回类型和它们的参数。
- 函数式编程语言将函数视为值并将它们作为参数传递给函数的能力使代码更具可读性和易于理解。
- 测试和调试更容易。由于纯函数只接受参数并产生输出,因此它们不会产生任何变化,也不会接受输入或产生一些隐藏的输出。它们使用不可变值,因此在使用纯函数编写的程序中检查某些问题变得更容易。
- 它用于实现并发/并行,因为纯函数不会更改变量或它之外的任何其他数据。
- 它采用惰性求值,避免重复求值,因为值只在需要时才求值和存储。
缺点:
- 有时编写纯函数会降低代码的可读性。
- 以递归方式编写程序而不是使用循环可能有点吓人。
- 编写纯函数很容易,但将它们与应用程序的其余部分和 I/O 操作结合起来却是一项艰巨的任务。
- 不可变值和递归会导致性能下降。
应用:
- 它用于数学计算。
- 在需要并发或并行的地方需要它。
事实:Whatsapp 的 9 亿用户只需要 50 名工程师,因为 Erlang 用于实现其并发需求。 Facebook 在其反垃圾邮件系统中使用 Haskell。