programming-languages - 闭包中的副作用,它们仍然是纯功能性的吗?

标签 programming-languages functional-programming lisp

作为函数式编程的新手,我花了很多精力想知道“这是做事的函数式方式吗?”显然,递归与迭代非常简单,递归显然是函数式的处理方式。但以闭包为例。 我已经使用 Lisp 学习了闭包,我知道闭包是函数和环境(听起来很像状态和行为)的组合。例如:

(let ((x 1))
           (defun doubleX()
              (setf x (* x 2))))

这里我们有一个在 x 变量的环境中定义的函数 doubleX。我们可以将这个函数传递给其他函数,然后调用它,它仍然可以引用 x 变量。该函数可以继续引用该变量,即使它是在定义该变量的环境之外调用的。我见过的很多关于闭包的例子都是这样的。其中setf用于改变词法变量的值。这让我感到困惑,因为:

1.) 我认为 setf 是邪恶的。主要是因为它会引起副作用,而且显然它们也是邪恶的。

2.) 这真的是“功能性”的吗?似乎只是一种保持全局状态的方式,我认为函数式语言是无状态的。

也许我只是不理解闭包。有人可以帮帮我吗?

最佳答案

你是对的,使用闭包来操作状态并不是纯粹的函数式的。 Lisp 允许您以函数式风格编程,但它并不强制您这样做。我实际上更喜欢这种方法,因为它允许我在纯功能性和修改状态的便利性之间取得务实的平衡。

您可能会尝试编写一些从外部看起来功能强大但为了提高效率而保持内部可变状态的东西。一个很好的例子是内存,你可以记录所有以前的调用来加速像斐波那契这样的函数,但是由于函数总是为相同的输入返回相同的输出并且不修改任何外部状态,它可以被考虑从外部发挥作用。

关于programming-languages - 闭包中的副作用,它们仍然是纯功能性的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/293567/

相关文章:

http - 用于制作发出 HTTP 请求的监控服务的推荐语言

c++ - 为什么你会想要创建一个名为 *foo() 而不仅仅是 foo() 的方法?

Haskell 用于 Lambda 演算、类型推断

lisp - 学习 Lisp。似乎无法从一个函数中获取值并在另一个函数中使用它

c# - Eric Lippert 的挑战 "comma-quibbling",最佳答案?

programming-languages - 如何为应用程序创建计算机或脚本语言?

r - 改变 R 中闭包的父环境(一个好主意)?

functional-programming - Ocaml 模式匹配问题

list - Lisp:给定级别 k 上的节点列表

function - 在 Lisp 中乘以 2 个列表