当通信工程毕业生遇上Reactive Programming

初遇Reactive Programming

第一次看到Reactive Programming是在学Functional Programming in Scala的最后,Martin说会再开一门高级一点的Functional Programming的课,于是就去查,发现他开的另一门课叫做Principles of Reactive Programming,介绍说这门课就是前面ProgFun的后续课程,出于好奇,就去查了一下Reactive Programming。以下来自Wikipedia:

In computing, reactive programming is a programming paradigm oriented around data flows and the propagation of change.

虽然不是很明白到底是什么意思,但看起来很厉害的样子。于是就开始学习Reactive的公开课。

懵懂Reactive Programing

上了两周课,Martin从复习Functional Programming开始,然后讲到Monad,再讲到Stateful Programming——也就是传统OOP的有状态编程,就是不提Reactive Programming。而且因为在web开发中已近存在了Responsive Programming(响应式编程),Reactive Programming要怎么翻译我也想不明白。

在这期间,查阅了一些akka的资料,也看了一些如elm.js,Rx之类的框架,还在Reactive Menifesto上签了名字,尽管没搞清楚Reactive Programming是什么,但至少知道Reactive Programming是一个比较先进(?),比较前沿的分布式系统编程范式,秉承我一贯的作风,一个东西只要够“新”,我就想学学看,于是准备深入研究下去。

了解Reactive Programming

说说到目前为止,通过Reactive那门课,以及一些其他资料总结出来的我个人对于Reactive Programming的理解吧。

看了Reactive课程第二周里数字电路仿真的例子,我会想起学习VHDL/Verilog的时候,设计信号处理程序通常是把一个大的组件拆分成一些小的组件,这些小的组件有一些输入输出的端口,然后通过编程定义每个小的组件在各个激励信号输入时的输出,最后把各个小组件连接起来,就可以实现一个完整的信号处理功能。

这和设计分布式系统异曲同工,Reactive Programming强调各个系统组件的松耦合与功能自治,由外界的激励信号触发内部的逻辑运算,输出信号可以继续传给另一个组件,也可以作为最终结果输出。这是我对Reactive Programming的第一个理解:

像设计数字电路一样设计分布式系统

在设计数字电路的过程中,最重要的是要理解信号是如何在电路中流转的,信号从一个组件的输入端流入,从输出端流出,再流入下一个组件,同时,一个信号可能作为输入流入多个组件,一个组件的输入可能来自多个组件的输出。所以在设计数字电路时要确保信号流动的正确,同时某个信号的改变能够正确的传播到各个组件。

而Reactive Programming处理的是数据,正如Wikipedia中定义的,Reactive Programming是围绕数据流以及变化传播发展而来的一种编程范式,当把数据流想象成电子线路中的信号流,作为通信专业毕业生的我,突然有种“守得云开见月明”的感觉。这是我的第二条理解:

将数据流想象成信号流进行处理

一段信号在数字电路中能够进入一个个组件,组件的输出又可以作为信号进入其他组件,信号在经过一个个组件的过程中,内容也许会经过处理而改变,但是其形式依然是信号,依旧可以当做其他组件的输入。如果一个电路的输入信号超过了电路可接受的信号范围,就需要在电路的输入端加入一个信号放大器(或者变压器)来调整信号的幅度。这是为什么数字电路可以做到组件拆分,然后可以很容易的组合成复杂功能的组件。

数据不是信号,数据的格式各式各样,如何在分布式系统中归一化数据,做到数据可以畅通无阻的在各个组件之间流转呢?这个归一化的诀窍就在于“Monad”。关于Monad的介绍,完全足够通过一系列文章来介绍,这里暂不详述。将其作为第三条理解列在这里:

利用Monad归一化数据使得数据流可以像信息流一样在系统中无障碍流转

数字电路设计的高阶过程是状态机的设计,即某个组件自身具有状态,在接受输入激励信号时,输出信号会根据输入信号和自身状态计算出来,同时组件状态也会改变,将各个状态流转过程连接起来,就成为了数字电路的状态机,从状态机流转图可以看出一个组件的完整逻辑。

想到这一层后,终于理解了为什么Martin在Reactive课程——Progfun的后续课程——中一开始就要介绍Stateful Programming。于是我得到了第四条理解:

用可变参数标记组件的状态,实现数据处理的状态机

猜想Reactive Programming

仔细想来,Reactive Programming的思想和人工神经网络异曲同工,而它们的本源其实是我们人类自己的大脑结构。大脑中的突触各自独立处理数据,彼此之间通过轴突和树突进行连接,一旦某个突触感应带外来信号的激励,马上就会触发其附近的突触进行相应,信号就这样不断扩散出去。

说的夸张一点,Reactive Programming其实是在将人的思考方式引入现实的编程中,作为分布式系统设计的范式。看看Reactive Menifesto的第一段:

Organisations working in disparate domains are independently discovering patterns for building software that look the same. These systems are more robust, more resilient, more flexible and better positioned to meet modern demands.

正如人类的大脑思考模型是自然选择的结果,Reactive Programming的范式是从各个不同组织实现的不同大型分布式系统中总结抽象出来的。物竞天择,适者生存。Reactive Programming目前还处于发展的起步阶段,相信未来会有更多的人接受它。