作为函数式编程的新手,我耗费了大量的精力,想知道“这是做事的功能性方法吗?”显然,递归与迭代非常简单,很明显递归是功能性的做事方式。 但是以闭包为例。 我已经了解了使用Lisp的闭包,我理解闭包是一个函数和一个环境的组合(听起来很像状态和行为)。 例如:

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

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

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

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

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

#1楼 票数:12 已采纳

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

您可能尝试的是从外部编写看似有用的东西,但保持内部可变状态以提高效率。 一个很好的例子就是memoization,你可以记录所有以前的调用来加速像fibonacci这样的函数,但是因为函数总是为同一个输入返回相同的输出并且不修改任何外部状态,所以可以考虑从外面发挥作用。

#2楼 票数:8

闭包是一个穷人的对象(反之亦然),请参阅

什么时候关闭?

我的回答。 因此,如果您打算在非OO应用程序中使用副作用来管理状态,那么关闭over-mutable-state确实是一种简单的方法。 不可改变的替代品“不那么邪恶”,但99.9%的语言提供可变状态,并且它们不可能都是错误的。 :)明智地使用可变状态是有价值的,但是当与闭包和捕获一起使用时,它可能特别容易出错,如此处所示

关于lambdas,捕获和可变性

在任何情况下,我认为你看到“这么多这样的例子”的原因是解释闭包行为的最常见方法之一就是展示一个像这样的小例子,其中一个闭包捕获一个变量,从而成为一个迷你-stateful-object,封装了一些可变状态。 这是一个很好的例子,可以帮助确保您了解构造的生命周期和副作用影响,但并不认可在整个地方使用此构造。

大部分时间关闭,你只需关闭值或不可变状态,并且“不注意”你正在做它。

#3楼 票数:2

Common Lisp和Scheme不是纯粹的功能。 Clojure主要是功能性的,但仍然不是纯粹的。 Haskell是我所知道的唯一纯粹功能性的语言,我甚至不能提到另一种语言的名称。

事实是,在纯粹的功能环境中工作非常困难(去学习Haskell并尝试在其上编程)。 因此,所有这些函数式编程语言真正实现的是允许函数式编程,但不强制执行。 功能编程非常强大,因此请尽可能地使用它,何时不能使用。

对于即将到来的年龄而言,重要的是,任何具有功能性的东西都是可以兼容的,因此避免产生副作用或尽可能使用最小的程序子集是有意义的。

  ask by Tim Merrifield translate from so

未解决问题?本站智能推荐:

1回复

在Lisp中创建命名的本地列表

在 Lisp 中创建本地命名列表的正确方法是什么? 我看到了全局列表但我想创建一个本地列表。 类似于下面的那个 谢谢
9回复

C#与LISP中的函数式编程

已关闭 。 这个问题是基于观点的 。 它当前不接受答案。 想改善这个问题吗? 更新问题,以便通过编辑此帖子以事实和引用的形式回答
12回复

无法使用静态语言创建应用功能?

我已经阅读过像Scala或Haskell这样的静态类型语言,无法创建或提供Lisp apply函数: 或者可能 这是真的吗?
12回复

您可以使用哪种语言动态地重写功能?

我最近有必要动态地在javascript中重写javascript函数。 我做的很容易,而且有多么有趣,让我很震惊。 在这里我有一些HTML: 我无法更改输出的HTML,但我需要在该链接中添加一个额外的参数。 我开始考虑它,并意识到我可以这样做: 它就像一个冠军! excelE
2回复

F#中的无类型/类型代码引用与宏观卫生之间是否存在关联?

我想知道F#中的无类型/类型代码引用与宏系统的卫生之间是否存在关联。 他们是否用各自的语言解决相同的问题,还是他们分开关注?
4回复

坚持Scala中功能范式的功效

我最近买了Scala编程 ,并一直在阅读它。 语言肯定不是我的预期! 具体来说,除了Lisp宏和Haskell的类型级别副作用隔离之外,它似乎实现了我所知道的几乎所有编程语言的想法。 坦率地说,它让我有些不知所措。 虽然我认为拥有这么多工具很好,但我真的只是在JVM上寻找一种强类型的函
10回复

在Scala中编写功能强大但功能强大的图像处理库

我们正在为Scala(学生项目)开发一个小型图像处理库。 该库完全正常(即没有可变性)。 图像栅格存储为Stream[Stream[Int]] ,以最少的努力利用延迟评估的好处。 但是,在对映像执行一些操作时,堆会变满,并OutOfMemoryError 。 (例如,在JVM堆耗尽空间之
3回复

CLR的功能开发

如果已经询问并回答了这个问题,请指出现有的问答,我会删除这个问题。 我确实看了,没有看到这个答案。 除了F#之外,CLR平台还主要是函数式语言(如LISP,Scheme,Haskell等)吗? 我说“主要是功能性的”因为认识到CLR语言具有像(Iron)Python这样的功能结构,但我不