"懒惰求值"和"响应式编程"

3
有没有例子可以演示惰性求值与响应式编程的不同之处?或者它们非常相似吗?
给定c = 3;,无论代码如何实现,两种方法都需要至少在内部实现b = c + 2;,例如int b() {return c + 2;}。在两种情况下,只有在需要其值时才知道b是什么,然后进行计算。
描述这种方法的名称是什么?
那么响应式编程使用或模拟惰性求值吗?使用惰性求值的语言以反应式方式编程吗?

1
“惰性求值”是一种规约策略,“响应式编程”是一种编程风格,通常使用惰性定义的结构,因此它们并不真正处于相同的抽象层级。 “函数式”的含义对我来说并不清楚。 - Kristopher Micinski
1
仍然有些困惑,因为您需要正确地限定您的问题范围:例如,在Haskell中使用功能响应式编程(编程风格)可以与调用按需规约(语言的特性,用于支持FRP)相对比。逻辑上,一个位于“较低级别”的位置。但这可能不是您想要的答案。 - Kristopher Micinski
1个回答

8

您好,您似乎将惰性求值和响应式编程视为相同的“逻辑层次”。

对我来说,惰性求值是一种语言工具,允许存在和操作无限数据。 (数据具有某种“有限结构”,但在您拉取尽可能多的数据后仍然是无限的。)如果您思考一下并尝试一些示例,您会发现在存在无限数据结构时具有惰性求值是很好的,因为使用这些值时不会“永远循环”。 (虽然还有其他用途可用于惰性求值,但有时肯定可以获得一些性能提升。)

维基百科定义了响应式编程:

在计算机中,响应式编程是一种围绕数据流和变化传播的编程范型。这意味着应该能够轻松地在使用的编程语言中表达静态或动态数据流,并且底层执行模型将自动通过数据流传播更改。

对我来说,这与惰性求值并不相关。惰性求值只意味着你只计算需要做更多工作的答案,然后保留一个占位符(通常称为“thunk”),以便在需要时让你做更多工作,从而计算更多答案。(顺便说一句,这种“尽可能多地获取所需”能力正是使用惰性求值处理无限数据的关键。)
相比之下,响应式编程允许你简洁地定义数据流如何传播。 (例如,反应框架将使您能够设置您提供的示例而不必明确使用回调和函数指针来实现它。)但实际上,这条线非常模糊。 当然,有在命令式语言中的响应式框架:大多数人会称GUI框架为响应式。
相比之下,在functional reactive programming(FRP)中,您可以声明性地指定响应式数据。 这是通过Haskell语言的惰性实现“底层”完成的(在那种特定情况下),因为这是最适合进行更新的方法(因为它最直接符合该范例)。
但是在像C或C++这样的语言中,您通常通过函数指针或回调进行反应式编程,没有明确的惰性求值概念。当然,在底层可能会有一些惰性来支持这种东西,但您并不真正处于正确的语义级别以进行区分,在这种情况下,您通常可以使用惰性“技巧”来加速反应式框架(它按需更新某些东西 - 例如GUI - 当用户使用更多部分时)。

我想我可能明白了,感谢您的回答。 - alan2here
1
我看到了这篇文章,因为我有完全相同的问题。答案非常好。我相信我和OP之所以会问这个问题,是因为如果你看一下像Bacon.js或Lazy.js这样的库,它们的实现似乎可以很容易地通过使用响应式编程范例(例如,使用流)来实现。正如你所暗示的那样,响应式编程与无限集合无关,但我面临的问题可以从惰性求值中受益而不需要无限集合(对大量数据进行过滤)。 - Izhaki

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接