写这篇文章的时候,一件事被我突然意识到了。文本被我写出来、被我保存到文件里。这已经不是计划,而是执行。因为与真实世界的交互正在被我进行。我的文字被世界读到,内容被文件系统存下,这些都是副作用。在此之前的好几个月里,那些概念被我一直在脑子里转,语言学、谓词、Monad、柯里化这些概念被我翻来覆去地转。那种状态才是真正的计划阶段。东西只在脑子里空转,不被落地,不被世界摩擦。
这个发现之后,一个长久的习惯被我重新审视了。我一直太喜欢做计划。计划阶段被我感受到最自由的时光,理想主义带来的自由感被我当成多巴胺释放一样的舒适。计划出炉的那一刻,被我内心觉得已经懂了、已经掌控了。但后来被我慢慢明白的是,那种舒服是从别处让渡来的。代价就是执行阶段的痛苦被我延后了、被我忽略了。
纯函数式编程给了我一个很好的类比。一个没有任何副作用的纯函数式程序,被我视作纯粹的蓝图。理想世界里的计算关系被它描述,现实不被它交互,文件不被它读取,屏幕不被它写入,用户不被它输入。它在数学上完美,但无法落地。底层的求值表达式才被用来运行程序。那些表达式本身就是 handler,操作系统交互被我交给它们,硬件交互被我交给它们,外部世界交互也被我交给它们。蓝图形制纯粹,求值沾染副作用,两者缺一不可。
这个道理也被我放进了生活。那套纯函数的定义集合就像计划,逻辑上自洽,但脱离真实世界。真正有效的规划从来不是凭空产生的,大量的观察和调研之上才能建立改善方案,而不是开天辟地式的创造。现实世界的判断如果被包含在规划里,那已经不是纯粹的计划了,执行的考量已经被掺入其中。
柯里化告诉了我另一个道理。Haskell 中只有单值函数被支持,多参数函数必须写成柯里化的形式,一个函数返回另一个函数,不断嵌套下去。一个复杂问题被这种线性拆解的方式变成了一条链条。每个步骤只有一件事被处理,结果被交给下一步。推理性问题上这个策略非常有效,链条上的每个环节都可以被独立验证、被完全复现、被数学严谨。但弊端也被我看见,链条的任何一个环节断裂,整体也就失败了。这是一种逻辑性的脆弱,每一步被预设为按预期执行。
复杂问题应该全局审视还是逐步深入,这取决于问题的类型和资源的约束。推理性问题适合链条式拆解,统筹管理类问题需要全景式把握。资源有限的时候,全局被我用来看资源分配。只有对一个流程或领域需要精确理解时,深入拆解才被我采用。没有一种方法放之四海而皆准。
Lean Startup 的 Build Measure Learn 循环也说了相似的事。快速失败不是目标,低成本暴露错误才是。通过 MVP 尽快开始学习,真实的反馈被用来修正假设。这和 Haskell 的哲学出奇一致,问题不被假装不存在,而是被放进一个可观察、可管理的结构。蓝图阶段没有被我知道哪个假设是错的,只有到了执行阶段,答案才被世界告诉我。
知行合一不是道德要求,而是认知的必然,这种观点被我越来越强烈地持有。手不动,东西就在脑子里空转。小行动被我做出就是最好的状态。即使不完美的文字和粗糙的尝试,也比停留在计划阶段有价值。执行的成果才是客观的证明,不依赖自我感受,就在那里,可以被检验、被推翻、被改进。
答案已经被我选清楚了。如果只能选一个阶段,我选执行。世界被我对抗,难题被我攻克,痛苦被我承受,但真实的结果,只有它能被产生。
参考文献
- Haskell Language. Haskell 2010 Language Report. https://www.haskell.org/definition/haskell2010.pdf
- Ries, E. (2011). The lean startup: How today’s entrepreneurs use continuous innovation to create radically successful businesses. Crown Business.
- Dalhousie University. Currying - CSCI 3137: Haskell Programming. https://web.cs.dal.ca/~nzeh/Teaching/3137/haskell/first_steps/basic_types/functions/curry/
- The Lean Startup. Methodology - Build-Measure-Learn. https://theleanstartup.com/principles
- Investopedia. Lean Startup: Key Differences from Traditional Business Models. https://www.investopedia.com/terms/l/lean-startup.asp