问题描述
我已阅读关于反应式编程的维基百科文章.我还阅读了关于函数式反应式编程的小文章.描述很抽象.
I've read the Wikipedia article on reactive programming. I've also read the small article on functional reactive programming. The descriptions are quite abstract.
- 函数式反应式编程 (FRP) 在实践中意味着什么?
- 反应式编程(相对于非反应式编程?)由什么组成?
我的背景是命令式/面向对象语言,因此如果能提供与此范式相关的解释,我们将不胜感激.
My background is in imperative/OO languages, so an explanation that relates to this paradigm would be appreciated.
推荐答案
如果您想体验 FRP,可以从旧的 Fran 教程 来自 1998 年,有动画插图.对于论文,从 Functional Reactive Animation 开始,然后访问以下链接我主页上的出版物链接和 FRP 链接.org/haskellwiki/Haskell" rel="noreferrer">Haskell wiki.
If you want to get a feel for FRP, you could start with the old Fran tutorial from 1998, which has animated illustrations. For papers, start with Functional Reactive Animation and then follow up on links on the publications link on my home page and the FRP link on the Haskell wiki.
就我个人而言,在讨论如何实施 FRP 之前,我喜欢考虑 FRP 意味着什么.(没有规范的代码是没有问题的答案,因此甚至没有错".)因此,我不会像 Thomas K 在另一个答案(图形、节点、边、触发、执行等)中那样用表示/实现术语来描述 FRP.有许多可能的实现风格,但没有一个实现说明 FRP 是什么.
Personally, I like to think about what FRP means before addressing how it might be implemented.(Code without a specification is an answer without a question and thus "not even wrong".)So I don't describe FRP in representation/implementation terms as Thomas K does in another answer (graphs, nodes, edges, firing, execution, etc).There are many possible implementation styles, but no implementation says what FRP is.
我确实对 Laurence G 的简单描述产生了共鸣,即 FRP 是关于代表‘随时间变化’的值的数据类型".传统的命令式编程只是通过状态和突变间接地捕获这些动态值.完整的历史(过去、现在、未来)没有一流的代表.此外,只有离散演化值可以(间接)被捕获,因为命令式范式在时间上是离散的.相比之下,FRP 可以直接捕捉这些不断发展的价值,并且不断不断地发展价值.
I do resonate with Laurence G's simple description that FRP is about "datatypes that represent a value 'over time' ".Conventional imperative programming captures these dynamic values only indirectly, through state and mutations.The complete history (past, present, future) has no first class representation.Moreover, only discretely evolving values can be (indirectly) captured, since the imperative paradigm is temporally discrete.In contrast, FRP captures these evolving values directly and has no difficulty with continuously evolving values.
FRP 也很不寻常,因为它是并发的,不会与理论相冲突.困扰命令式并发的务实老鼠窝.从语义上讲,FRP 的并发是细粒度、确定和连续.(我说的是意义,而不是实现.实现可能涉及也可能不涉及并发性或并行性.)语义确定性对于推理非常重要,无论是严谨的还是非正式的.虽然并发为命令式编程增加了极大的复杂性(由于不确定性交错),但在 FRP 中却毫不费力.
FRP is also unusual in that it is concurrent without running afoul of the theoretical & pragmatic rats' nest that plagues imperative concurrency.Semantically, FRP's concurrency is fine-grained, determinate, and continuous.(I'm talking about meaning, not implementation. An implementation may or may not involve concurrency or parallelism.)Semantic determinacy is very important for reasoning, both rigorous and informal.While concurrency adds enormous complexity to imperative programming (due to nondeterministic interleaving), it is effortless in FRP.
那么,什么是 FRP?你本可以自己发明的.从这些想法开始:
So, what is FRP?You could have invented it yourself.Start with these ideas:
动态/不断发展的价值观(即随着时间推移"的价值观)本身就是一流的价值观.您可以定义它们并组合它们,将它们传递给 &出功能.我称这些为行为".
Dynamic/evolving values (i.e., values "over time") are first class values in themselves. You can define them and combine them, pass them into & out of functions. I called these things "behaviors".
行为是由一些原语构成的,如恒定(静态)行为和时间(如时钟),然后是顺序和并行组合.n 行为是通过应用 n 元函数(在静态值上)逐点"组合的,即随着时间的推移而连续.
Behaviors are built up out of a few primitives, like constant (static) behaviors and time (like a clock), and then with sequential and parallel combination. n behaviors are combined by applying an n-ary function (on static values), "point-wise", i.e., continuously over time.
为了解释离散现象,有另一种类型(系列)的事件",每个事件都有一个(有限或无限)发生的流.每个事件都有一个关联的时间和值.
To account for discrete phenomena, have another type (family) of "events", each of which has a stream (finite or infinite) of occurrences. Each occurrence has an associated time and value.
要提出可以构建所有行为和事件的组合词汇,请举出一些例子.继续分解成更通用/更简单的部分.
To come up with the compositional vocabulary out of which all behaviors and events can be built, play with some examples. Keep deconstructing into pieces that are more general/simple.
为了让你知道你在坚实的基础上,给整个模型一个组合基础,使用指称语义的技术,这只是意味着(a)每个类型都有一个相应的简单 &精确的数学类型含义",以及(b)每个原语和运算符都有一个简单的 &作为成分含义的函数的精确含义.永远不要将实施注意事项混入您的探索过程中.如果这个描述对你来说是胡言乱语,请参阅 (a) 具有类型类态射的指称设计, (b) 推拉函数式反应式编程(忽略实现位),以及 (c) 指称语义em> Haskell wikibooks 页面.请注意,指称语义有两个部分,来自其两位创始人 Christopher Strachey 和 Dana Scott:更简单的和更有用的 Strachey 部分和更难、更没用的(对于软件设计)Scott 部分.
So that you know you're on solid ground, give the whole model a compositional foundation, using the technique of denotational semantics, which just means that (a) each type has a corresponding simple & precise mathematical type of "meanings", and (b) each primitive and operator has a simple & precise meaning as a function of the meanings of the constituents.Never, ever mix implementation considerations into your exploration process. If this description is gibberish to you, consult (a) Denotational design with type class morphisms, (b) Push-pull functional reactive programming (ignoring the implementation bits), and (c) the Denotational Semantics Haskell wikibooks page. Beware that denotational semantics has two parts, from its two founders Christopher Strachey and Dana Scott: the easier & more useful Strachey part and the harder and less useful (for software design) Scott part.
如果您坚持这些原则,我希望您或多或少会获得一些符合 FRP 精神的东西.
If you stick with these principles, I expect you'll get something more-or-less in the spirit of FRP.
我从哪里得到这些原则的?在软件设计中,我总是问同样的问题:这是什么意思?".指称语义为这个问题提供了一个精确的框架,并且符合我的审美(不像操作或公理语义,这两者都让我不满意).所以我问自己什么是行为?我很快意识到命令式计算的时间离散性质是对机器特定风格的一种适应,而不是对行为本身的自然描述.我能想到的对行为的最简单精确描述就是(连续)时间的函数",这就是我的模型.令人高兴的是,该模型可以轻松优雅地处理连续的、确定性的并发.
Where did I get these principles? In software design, I always ask the same question: "what does it mean?".Denotational semantics gave me a precise framework for this question, and one that fits my aesthetics (unlike operational or axiomatic semantics, both of which leave me unsatisfied).So I asked myself what is behavior?I soon realized that the temporally discrete nature of imperative computation is an accommodation to a particular style of machine, rather than a natural description of behavior itself.The simplest precise description of behavior I can think of is simply "function of (continuous) time", so that's my model.Delightfully, this model handles continuous, deterministic concurrency with ease and grace.
正确有效地实施这个模型是一个相当大的挑战,但那是另一回事了.
It's been quite a challenge to implement this model correctly and efficiently, but that's another story.
这篇关于什么是(函数式)反应式编程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!