我读过维基百科上关于响应式编程的文章。我还读过一篇关于函数式响应式编程的小文章。这些描述相当抽象。
函数式响应式编程(FRP)在实践中意味着什么? 反应式编程(相对于非反应式编程?)由什么组成?
我的背景是命令式/OO语言,所以与此范例相关的解释将受到赞赏。
我读过维基百科上关于响应式编程的文章。我还读过一篇关于函数式响应式编程的小文章。这些描述相当抽象。
函数式响应式编程(FRP)在实践中意味着什么? 反应式编程(相对于非反应式编程?)由什么组成?
我的背景是命令式/OO语言,所以与此范例相关的解释将受到赞赏。
当前回答
看看Rx, net的响应式扩展。他们指出,使用IEnumerable,你基本上是从流中“拉”出来的。IQueryable/IEnumerable上的Linq查询是集合操作,从集合中“吸”出结果。但是在IObservable上使用相同的操作符,你可以编写“反应”的Linq查询。
例如,您可以编写这样的Linq查询 (from MyObservableSetOfMouseMovements中的m m.X<100 m.Y<100 选择新的点(m.X,m.Y))。
有了Rx扩展,就是这样:你有UI代码,它会对传入的鼠标移动流做出反应,并在你处于100,100框时进行绘制……
其他回答
对我来说,这是关于符号的2个不同的含义=:
在数学中,x = sint的意思是,x是sint的另一个名字。所以写x + y和sin(t) + y是一样的。函数式响应式编程在这方面就像数学:如果你写x + y,它是用t在使用时的任何值来计算的。 在类c编程语言(命令式语言)中,x = sin(t)是一个赋值:它意味着x存储在赋值时所取的sin(t)的值。
根据前面的答案,在数学上,我们似乎只是以更高的顺序思考。我们不认为值x具有类型x,而是考虑函数x: T→x,其中T是时间的类型,可以是自然数、整数或连续统。当我们用编程语言写y:= x + 1时,我们实际上是指方程y(t) = x(t) + 1。
在纯函数式编程中,没有副作用。对于许多类型的软件(例如,任何与用户交互的软件),在某种程度上副作用都是必要的。
在保持函数式风格的同时获得类似副作用的行为的一种方法是使用函数式响应式编程。这是函数式编程和响应式编程的结合。(你链接到的维基百科文章是关于后者的。)
响应式编程背后的基本思想是,有特定的数据类型表示“随时间”的值。涉及这些随时间变化的值的计算本身也具有随时间变化的值。
例如,您可以将鼠标坐标表示为一对随时间变化的整数值。假设我们有这样的东西(这是伪代码):
x = <mouse-x>;
y = <mouse-y>;
在任何时刻,x和y都是鼠标的坐标。与非响应式编程不同,我们只需要进行一次赋值,x和y变量将自动保持“最新”。这就是响应式编程和函数式编程协同工作的原因:响应式编程消除了对变量突变的需要,同时仍然允许您完成许多可以通过变量突变完成的工作。
如果我们在此基础上进行一些计算,得到的值也将是随时间变化的值。例如:
minX = x - 16;
minY = y - 16;
maxX = x + 16;
maxY = y + 16;
在这个例子中,minX总是比鼠标指针的x坐标小16。使用响应式感知库,你可以这样说:
rectangle(minX, minY, maxX, maxY)
一个32x32的方框将围绕鼠标指针绘制,并跟踪它的移动位置。
这是一篇关于函数式响应式编程的很好的论文。
关于响应式编程的简短而清晰的解释出现在Cyclejs -响应式编程中,它使用了简单和可视化的示例。
一个[模块/组件/对象]是反应性的意味着它是完全负责的 通过对外部事件的反应来管理自己的状态。 这种方法的好处是什么?这就是控制反转, 主要是因为[module/Component/object]对自己负责,使用私有方法来改进封装。
这是一个很好的起点,而不是一个完整的知识来源。从那里你可以跳到更复杂和更深入的文件。
Conal Elliott的论文《Simply efficient functional reactivity》(直接PDF, 233 KB)是一个相当好的介绍。相应的库也可以工作。
这篇论文现在被另一篇论文取代,推拉函数式反应性编程(直接PDF, 286 KB)。