当前的function反应式编程实现的状态是什么?

我试图在Haskell中直观地看到一些简单的自动物理系统(例如钟摆,机器人arm等)。 通常这些系统可以用类似的方程来描述

df/dt = c*f(t) + u(t)

u(t)代表某种“智能控制”。 这些系统看起来很适合function反应编程范例。

于是我拿起Paul Hudak写的“Haskell School of Expression”一书,发现那里介绍的领域专用语言“FAL”(对于functionanimation语言)实际上对我的简单玩具系统非常好用(尽pipe一些function,特别是integrate ,似乎有点懒得有效使用,但容易修复)。

我的问题是,对于更先进甚至实际应用而言,更成熟,最新,维护良好,性能优化的替代scheme是什么?

这个wiki页面列出了Haskell的几个选项,但我不清楚以下方面:

  1. 来自Conal Eliott的项目“反应式”的状态(据我所知)是这个编程范式的发明者之一,看起来有些陈旧。 我喜欢他的代码,但也许我应该尝试其他更新的替代scheme? 在语法/性能/运行时稳定性方面,它们之间的主要区别是什么?

  2. 引用2011年的一项调查 ,第6节,“ … FRP的实施仍然不够有效或足够可预测的性能,以有效地使用需要延迟保证的领域… ”。 虽然这项调查提出了一些有趣的可能的优化,但考虑到FRP已经有超过15年的历史了,我觉得这个性能问题可能至less在几年之内甚至是很难解决的。 这是真的?

  3. 调查的同一作者在博客中谈到“时间泄漏”。 这个问题是FRP独特的问题,还是我们用纯粹的非严格语言进行编程时普遍存在的问题? 你是否曾经发现,如果不够高性能的话,就很难稳定一个FRP系统的使用寿命?

  4. 这仍然是一个研究水平的项目? 人们喜欢工厂工程师,机器人工程师,财务工程师等,是否真正使用它们(以适合他们需要的whaterver语言)?

虽然我个人比较喜欢Haskell的实现,但我可以接受其他的build议。 例如,有一个Erlang实现将会特别有趣 – 那么拥有一个智能的,适应性的,自学习的服务器进程将非常容易!

现在,主要有两个实用的Haskell库,用于function性反应式编程。 两者都由单个人维护,但也从其他Haskell程序员那里得到代码贡献:

  • Netwire专注于效率,灵活性和可预测性。 它有自己的事件范例,可以用于传统玻璃钢不起作用的地方,包括networking服务和复杂的模拟。 风格:应用和/或箭头。 最初的作者和维护者:ErtugrulSöylemez(这是我)。

  • 反应型香蕉build立在传统的玻璃钢范例之上。 虽然它是实用的,但它也是经典玻璃钢研究的基础。 它的主要重点是用户界面,并有一个现成的接口wx。 风格:应用。 初始作者和维护者:Heinrich Apfelmus。

你应该尝试他们两个,但根据你的应用程序,你可能会发现其中一个更适合。

对于游戏,networking,机器人控制和模拟,你会发现Netwire是有用的。 它为这些应用程序提供了现成的线路 ,包括各种有用的差分,积分和大量用于透明事件处理的function。 有关教程,请访问我链接的页面上的Control.Wire模块的文档。

对于graphics用户界面,目前你最好的select是反应香蕉。 它已经有了一个wx接口(作为一个单独的库reactive-banana-wx),Heinrich在这方面博客了很多关于FRP的知识,包括代码示例。

回答您的其他问题:FRP不适用于需要实时可预测性的情况。 这主要归功于Haskell,但不幸的是FRP很难在低级语言中实现。 一旦Haskell本身变成实时,FRP也会到达那里。 从概念上讲,Netwire已经准备好了实时应用程序。

时间泄漏不再是一个问题,因为它们主要与monadic框架有关。 实际的FRP实现根本不提供一个monadic接口。 Yampa已经开始了这个,Netwire和反应香蕉都build立在这个基础上。

我知道现在没有使用玻璃钢的商业或其他大型项目。 图书馆已经准备好了,但我认为人们还没有。

虽然已经有一些很好的答案,但我会试着回答你的具体问题。

  1. 由于时间泄漏问题,被动无法用于严重的项目。 (见#3)。 目前devise最相似的图书馆是反应型香蕉,它是以react native为灵感开发的,并与Conal Elliott进行了讨论。

  2. 虽然Haskell本身不适用于硬实时应用程序,但在某些情况下,可能会将Haskell用于软实时应用程序。 我不熟悉目前的研究,但我不认为这是一个不可逾越的问题。 我怀疑像Yampa这样的系统或像Atom这样的代码生成系统可能是解决这个问题的最好方法。

  3. “时间泄漏”是特定于可切换FRP的问题。 当系统无法释放旧对象时会发生泄漏,因为如果未来某个时候会发生切换,则可能需要这些对象。 除了内存泄漏(可能非常严重)之外,另一个结果是,当交换机发生时,系统必须暂停,而旧对象的链条则被移动以产生当前状态。

不可切换的frp库如Yampa和较旧版本的反应型香蕉不会受到时间泄漏的影响。 可切换的frp库通常采用以下两种scheme之一:或者它们具有创buildFRP值的特殊“创build单元”,或者使用“老化”types参数来限制可能发生切换的上下文。 elerea (可能netwire?)使用前者,而最近的反应香蕉和柚子使用后者。

“切换frp”是指实现Conal的functionswitcher :: Behavior a -> Event (Behavior a) -> Behavior a或相同的语义。 这意味着networking的形状可以在运行时dynamic切换。

这与ertes关于monadic接口的说法并不矛盾:事实certificate,为一个Event提供一个Monad实例会使得时间泄漏成为可能,并且通过上述两种方法之一,不可能再定义等价的Monad实例。

最后,虽然FRP还有很多工作要做,但我认为一些较新的平台(反应式香蕉,elerea,netwire)已经足够稳定和成熟,您可以从中构build可靠的代码。 但是你可能需要花费大量时间来学习这些细节,以了解如何取得良好的performance。

我将列出Mono和.Net空间中的一些项目,以及不久前发现的Haskell空间项目。 我将从Haskell开始。

榆树 – 链接

其描述按照其网站:

榆树的目标是使前端Web开发更愉快。 它引入了一种新的GUI编程方法,纠正HTML,CSS和JavaScript的系统问题。 Elm允许您快速轻松地使用可视化布局,使用canvas,pipe理复杂的用户input以及逃离callback地狱。

它有自己的FRP变体。 从玩它的例子来看,它似乎相当成熟。

react native扩展 – 链接

从头版描述:

Reactive Extensions(Rx)是一个库,用于使用可观察序列和LINQ风格的查询运算符来组合asynchronous和基于事件的程序。 使用Rx,开发人员使用Observable来表示asynchronous数据stream,使用LINQ运算符查询asynchronous数据stream,并使用Scheduler在asynchronous数据stream中对并发进行参数化。 简单地说,Rx = Observables + LINQ +调度程序。

无功扩展来自MSFT,并实现了许多优秀的运算符,以简化处理事件。 这是几天前开源的 。 它非常成熟,用于生产; 在我看来,它将是一个更好的Windows 8 API API比TPL库提供; 因为可观测量既可以是冷热的,也可以是重试/合并等,而任务总是代表热的或完成的计算,这些计算可以是运行的,故障的或完成的。

我已经写了使用Rx的服务器端代码asynchronous速度,但我必须承认,写在C#function可能有点烦人。 F#有几个包装器,但是很难跟踪API开发,因为这个组织相对封闭,不像其他项目那样被MSFT推广。

它的开源来自于IL-to-JS编译器的开源,所以它可能在JavaScript或者Elm上运行的很好。

您可以使用消息代理(如RabbitMQ和SocksJS)很好地将F#/ C#/ JS / Haskell绑定在一起。

Bling UI工具包 – 链接

从头版描述:

Bling是一个基于C#的库,用于轻松编辑Microsoft WPF / .NET上的图像,animation,交互和可视化。 金光闪闪是面向devise技术人员,即有时编程的devise师,以帮助快速build立丰富的UIdevise思想。 学生,艺术家,研究人员和业余爱好者也会发现Bling作为快速expression想法或可视化的工具很有用。 Bling的API和构造针对快速编程丢弃代码进行了优化,而不是仔细编程生产代码。

免费的LtU文章 。

我已经testing过这个,但没有为客户端项目工作。 它看起来很棒,有很好的C#操作符重载,形成值之间的绑定。 它使用WPF / SL /(WinRT)中的依赖项属性作为事件源。 其3Danimation在合理的硬件上运行良好。 如果我最终得到一个需要可视化的项目,我会使用它; 可能将其移植到Windows 8。

ReactiveUI – 链接

以前在MSFT的Paul Betts现在在Github上写了这个框架。 我已经非常广泛地使用它,并像模型一样。 它比Blink更具解耦性(使用Rx及其抽象的性质) – 使用它更容易地对unit testing代码进行unit testing。 用于Windows的github git客户端就是这样写的。

注释

对于大多数性能要求较高的应用来说,反应式模型足够高性能。 如果您正在考虑实时性,我敢打赌大多数GC语言都有问题。 Rx,ReactiveUI创build一些需要GCed的小对象,因为这是如何创build/处置订阅和中间值在callback的被动“monad”中进行的。 一般来说,在.Net上,我更喜欢反应式编程而不是基于任务的编程,因为callback是静态的(在编译时已知,没有分配),而任务是dynamic分配的(不知道,所有的调用都需要一个实例,垃圾创build),lambdas编译成编译器生成的类。

显然C#和F#是严格评估的,所以时间泄漏在这里不成问题。 JS也一样。 尽pipe如此,可重复或caching的观测值可能会有问题。