编程启示录:哥白尼的日心说

162 阅读4分钟

纠结的引言

虽然我知道大家都有自己习惯的编程方式,但我还是想向大家安利这种新的。我反复纠结这种安利是否有意义,是否徒劳,别人可能不会接受安利,我也不指望在安利中能获得什么,那我为何还要浪费时间继续做下去?放弃的念头一直挥之不去。

我想了想,盘点我写过的所有代码,只有这个与哥白尼提出日心说时的心情一样令人振奋、激动,它或许尚不完美,但它更接近真相。虽然我没有布鲁诺的勇气,也没有卞和的坚持,但还是希望大家能有伯乐的眼光,认真看待这匹小马,多点包容,给予帮助让它更完善。

1a6c48688521eac7372114fa2377392f443947b1.jpg

一种新思想

开始之前先讲一句老话:一个装满苦瓜汁的杯子,要把苦瓜汁倒出之后才能继续倒入糖水。

缘起于顿悟。与大家一样,我也颇为擅长写代码,逻辑写得很棒,虽然写了许多年,但每次还是觉得又累又烦,写得越久这种感觉越强烈,为何非得如此!?
于是我萌生了一个大胆的想法:假设没有逻辑,代码还能否执行?
我就发现剔除逻辑部分后,代码就只剩下了数据变量,原来逻辑部分的意义只是为了修改这些数据变量而已。我从前以为的在适当的时机、条件去执行某个功能,不过是根据某个变量A的状态再去修改变量B的状态而已。换种方式理解就是:f(input)outputf(input)⇒output,即函数式编程。但这还没完,因为我们的程序不会简单到只需要一个函数,而是许许多多的函数串联堆砌起来的,要粘合堆砌这些函数,又免不了需要重新引入逻辑控制流,就又变成了我们习惯的写法,似乎又转回去了……

此刻我又有了另一个大胆的想法:是不是可以去掉函数变成这样 inputoutputinput⇒output
用人话来讲就是只描述变量间的转换关系,即 output 观察 input,当 input 更新时自动进行转换。这样一来,函数式编程的串联写法(驱动式)就转变为了描述变量间的转换关系,也即变量转换链,从驱动式写法变成了响应式写法,粘合函数间的控制流就被消除掉了。因为在变量转换链中,每个节点只需观察依赖的前置变量而不必考虑后续自己会驱动谁或被谁所依赖,彻底摆脱逻辑控制流。

至此,我貌似发现了一条与众不同的编程之路,一种新的编程思想:数据转换思想。

从算术方法到方程解法

在理论支持下,我尝试探索出了一种可行的新编程方法。

  1. 把游离的变量归纳到一起作为数据结构的字段,这样就能观察字段的更新了,为后续描述字段间的转换关系打好了基础。
  2. 然后自然想到形如 watch { obj.input } then { obj.output = xxx } 的写法。但这个写法其实有问题,必须得等到 obj 有值时才能开始执行,所以也难以观察字段 obj.aaa.bbb,那么就更不必说在 obj 有值前就能描述好完整字段转换链了。
  3. 我又想到一个不错的新写法:when { Struct.input } then { self.output = xxx }。既然 obj 可能为空,那么就为 obj 抽象一个 Struct 类型, 然后就可以在 Struct 上描述完整的字段转换链了。完美!

至此,就基本差不多了,一种新语言的雏形呼之欲出。但写一门语言成本太高,于是我用 TypeScript 写了一个工具 Imsure 来模拟,理论上也可以用其他语言来实现,欢迎感兴趣的朋友。更希望大家可以理解接受这种思想。

再后来我在日常使用中又有了新发现,这种写法在面对各种业务需求时出奇地好用,具有普适性,就像从算术方法到方程解法一样也具有普适性。

从传统编程需要根据具体业务需求设计不同的实现过程,到全然不用设计,只用一条普适的方法就能解决:

  1. 定义数据结构。(设未知数)
  2. 定义转换规则。(列方程式)
  3. 为字段赋值。(代入已知数)

至此,就再也不需要推导业务逻辑了。

以上内容叙述了:顿悟→推导→使用方法。不知道能理解的读者朋友有几个?也不知道能看到此文的读者有几个?若你有缘见到此文,烦请转发、点赞、评论一番把这顶上去增加点热度,为这种思想贡献一份力量,非常感谢!

这杆崭新的大旗🚩,你愿一起来扛吗?


相关链接
Imsure
Imsure-Demo