用函数式编程治愈冒名顶替综合症
十年的网络开发经历让我感觉自己就像尼奥在遇到墨菲斯之前一样。这个世界肯定出了什么问题。我有一些线索,但却无法确切地解释到底是什么。
我每天使用的语言是 JavaScript。最终,我决定成为一名老师,向初学者和初级开发者讲解如何制作真实的 Web 应用。
我转行不是因为觉得自己已经稳固了,事实上恰恰相反。我想当老师,是为了提升自己的技能,不断探索,并治愈我的“冒名顶替综合症”。
拿到学位并在某个领域工作十年之后,谁还会觉得自己像个骗子、永远的新手?当然是程序员。
但为什么呢?我会尝试解释我的发现。
我以前上编程课的时候,总是这样说:“成为一名优秀的程序员根本不需要数学。我们需要的是解决问题的人。”
当然还有:“万事皆有工具。如果你知道在哪里找到并使用正确的资源,你甚至不需要成为一名优秀的程序员。”
甚至:“由于行业变化如此之快,你必须
每年学习一个框架才能跟上趋势。”
当我们谈论质量时,我总是提倡使用精心选择的驼峰式变量名。当有人问我为什么网络如此混乱时,我会描述 JavaScript 的弱点和疲劳(JS,一种没人学的语言)、程序员的懒惰、缺乏测试/DevOps/设计模式/质量工具等等。
当谈到冒名顶替综合症时,即使我自己也患有这种病,我也只是试着安慰人们:“继续开发应用程序吧,它只是你的想法,它会随着你的成就而消失。”
然而,我的冒名顶替综合症并没有随着时间的流逝而消失——而我的成就却消失了。
我的所有网站和应用都消失了。我的第一个 PHP 和 ASP.NET 自定义 CMS、我的 Java 和早期 Node 后端、我的 jQuery 插件、我的 Dojo 应用、我的 Ruby on Rails 项目、我的 AngularJS 落地页和 Ionic 移动应用,甚至我最近用 Vue 1、Angular 2 beta 版和早期 React 开发的作品都消失了。
我知道原因。那些项目太大,难以改变,而且漏洞太多——技术易过时,投资流程不稳定,新程序员经验不足,无法扩展现有的代码库。
即使是最佳实践下完成的工作也会在(回调)地狱中灰飞烟灭、夭折甚至烧毁。领域驱动驱动 (DDD)、设计模式、API、微服务、测试驱动开发 (TDD)、linters + prettiers、注释、GitFlow、最佳框架和库、Docker、CI/CD 和 DevOps、KISS、Redux、ReactiveX、敏捷管理、任务运行器和转译器、结对编程和评审等等。
我们什么方法都试过了。但试了这么多,项目还是出了问题。代码库不停更新,直到变得太大,我们又得从头开始重新写代码。这显然是个恶性循环。
如果我一直都错了怎么办?十年的错误?
如果对于我们在网络开发以及整个计算机科学中造成的混乱有不同的解释呢?
如果我们错过的东西实际上与我所教的内容完全相反怎么办?
如果是这样,我们就反转指令。
- 不要再像热情的猴子补丁程序那样试图解决问题。
- 在不了解基础知识的情况下,不要组合不可靠的工具。
- 不要再把所有代码都关在笼子里,以免被我们将会创造的怪物所吓倒。
- 停止用更多的代码来填补无尽的空白。
- 停止选择名称或开发与多种问题相关且用途易逝的静态 API。
- 停止开发新的数据结构,而不发挥现有数据的潜力。
- 不要每个月都改变技术、框架和代码库——修改它们,使它们在 10 年后更加可靠和可用。
- 别再当骗子了。
函数式编程
您听说过函数式编程吗?
是的,当然,因为几年来,每种主流语言、公司和思想领袖都已朝着这个方向迈出了步伐。
但是函数式编程到底是什么呢?
两年前,我去了最近的大学图书馆,试图找到有关单子、Lambda 演算、半群、组合子、线性代数、高阶函数以及我们发现 FP 时出现的其他主题的书籍。
我天真地寻找计算机科学书籍,但一无所获。
几周前,为了备课,我又去了同一个地方,买了一本关于布尔代数的书。
图书馆管理员带我去了数学书架,在那里我发现了“圣杯”——50本关于函数式编程奇幻世界里所有知识的旧书。
我打开的第一本布满灰尘的书中清楚地解释了 Monoïd 以及可以用它们进行的操作。
那是一个顿悟的时刻,莫菲斯药丸就是这个架子。我十年来一直在寻找的答案非常简单:“数学很重要”。尽管答案就藏在眼前,我却“闭紧双眼”。我仍然无法完全理解莫诺伊德,但现在我能清楚地看到那条路,矩阵的绿色字符在我周围飘落。
为什么程序不运行?
为什么我们需要每两年彻底重写它们?
当然是因为他们缺乏数学!
我们想整天操纵“零”和“一”,但我们甚至不知道简单的(布尔)代数,如恒等性、交换性、结合性、幂等性等。
解决问题并非技能——花时间重新开发和修补(即使做得很巧妙)仍然会增加代码库,造成一种没人愿意偿还的“技术债”。
那么,我们需要什么呢?
我们需要的是更少的代码。
我们需要的是证明它有效。不是昂贵的“TDD证明”,而是一种肯定能解决所有问题的方法。
我们需要的是一种可扩展性,即除了 a、b 或 c 之外,变量无需使用任何其他名称。我们的函数将非常简单、通用、稳定、可组合,并且面向未来,确保现在和 30 年后都能以相同的方式读取和使用。
我们需要的不是无处不在的人为限制和工具来避免糟糕的代码或糟糕的做法,而是无处不在的代数。
我们需要的是停止冒名顶替,最终开始为计算机思考,像它一样思考。我们正在编程的这台机器,能够巧妙地计算一切的概念。这会很难。至少对我来说很难。
计算机启动后会做什么?
它从 DD 获取数据作为输入,并将其计算为我们设备所需的输出。然后,它等待新的输入,这使我们能够开发程序或应用程序来再次映射某些输出。
只有两种情况:
- 如果已经计算出来了,那么我们只需要内存。
- 如果要计算的话,我们需要一个函数。
我们为什么要把这么简单的事情复杂化呢?我们没有学习数学,而是选择创造一个充满流行文化语言和工具的神秘世界,这些语言和工具或多或少可以解决任何类型的问题。
每当我们试图随机应变时,就会产生更多的问题。
这是面向错误的编程。
在信息学的早期,人们仍然需要探索计算的方法。那时,人们可以找到变通的方法来组织一切,创造新的词汇和语言来重复使用基本的计算。
现在不了解和利用我们已有的东西真是太可惜了。计算机和语言非常可靠,它们可以通过一个精心设计的函数毫无差错地计算数万亿的数据。除了对纳米级晶体管的影响外,它仍然是可靠的,我们可以说这个函数是“纯粹的”。
谁擅长函数,并且知道所有函数的秘密?当然是数学家。
好好利用这股力量吧!CPU 工程师们已经完成了他们的工作。现在,让我们向他们展示我们的能力。更不用说,信息学领域的新问题与异步、多线程和并发有关——而这正是函数式编程 (FP) 的主要目的,也是它存在的意义。
那么我现在要教什么呢?
不要改变语言或框架,而是改变你的想法。
继续使用 docker、linters、DDD、TDD 以及任何可以帮助您交付可靠应用程序的东西。
但是,在你的日常工作中:
- 别再写太多代码、数据结构、API 和类了。少写点,直到你得到一个核心的、一行代码、一个参数、可复用的纯函数。精简代码,精益求精。
- 尝试像专业人士一样使用这些功能,并在您编写的精美过程之前和之后保留现实世界的“效果”。
- 开始逐步学习函数式编程。将其视为成为一名自信的高级程序员的数学先决条件。
- 开始使用 FP 世界中的函数,只是为了看看它们会将您引向何方(map、filter、reduce、pipe 等)。
- 开始编写你自己的高阶函数,然后从它们有用的数学特性中获益。
您想要一个设计模式来开始吗?
以下是适合任何规模项目的“洋葱”图案:
- 您的编程语言是一个隐含层,您必须彻底学习。
- 为你的语言中缺少的核心函数编写一层,例如“log”、“not”、“even”、“odd”、“concat”、“map”、“reduce”、“filter”、“compose”、“pipe”等等。或者,你可以使用现有的库,例如Ramda或Lodash,但如果有的话,最好好好学习一下。我们把它们称为“工具”。
- 一个包含“领域”函数和数据模型的层,您可以在领域、公司或业务的每个项目中重复使用它们。我们称之为助手。
- 当前程序功能和数据模型的层。我们称之为服务。
- 顶层是你的程序,也是你控制数据、函数和效果的地方。理想情况下,这是你唯一需要用前端框架来整合代码库的地方。因此,即使你更换了框架,其余部分也可以保留。
每一层都只是前几层的简单组合。如果你遵循这个顺序,那么你可以随时删除上一层并使用前一层。
对于小项目或 POC,只需使用两层或三层。
新一代程序员即将到来。全球数百万人正在学习和培训;高薪又有趣的工作带来的“吸力效应”进一步放大了他们的潜力。
大多数人认为,只要擅长解决问题,或者“了解什么是 public static void 方法”,或者“熟悉一个流行的框架”,就足以创建可运行的应用程序。如果你只需要一次性程序,情况确实如此。
你可以用这些幻想度过整个职业生涯,在拥有和我一样信仰体系的人身边寻求安慰。结果,未完成或无法完成的产品的日常生产更新问题会越来越多,就像 JavaScript 疲劳本身一样。
但希望依然存在。很多年轻的程序员还没有适应面向对象编程的经典历程,或者命令式编程。他们不想只用意大利面条式的代码来解决问题。有些人已经对函数式编程着迷了。
所以,趁还来得及,赶紧跳上FP这趟列车吧。互联网正处于原始混乱之中,但我们将携手重塑它。这将改变未来,而你将成为我们迫切需要的同事、导师或老师。
但是,请善待那些还不知道好消息的人,我们不想抛弃他们。启示可能需要时间。
我想提出一个假设,以更好地解释我自己的旅程。
JavaScript 为何如此迅速地流行起来?为什么一些程序员会爱上它,尽管它有明显的缺陷?我认为,正是因为它作为值的功能,才吸引了每一位使用它的程序员。
他们不知道为什么感觉这么好,但他们却待在那里,自然而然地变得雄辩,要求更多。也许这种直觉会引导你走向FP,就像我一样。不要等到多年后才睁开眼睛,今天就开始吧。
但要小心,如果 JavaScript 因为这个原因诱惑了你,而你从未学会如何管理它,那么最终你将得到有缺陷的代码。
那我呢?自从我开始使用这个范式以来,我的程序不仅变得更好,而且更加真实、更可控,最终真正可靠。我的代码库每天都在减少。
我从来没有在我的程序员/教师生涯中感到如此快乐,因为我终于知道自己在做什么。
重构现在成了一件乐事。感觉就像一场游戏,我会说:“哦!我可以这样分解它,它只是一些我已经知道的简单事物的组合!”
我还有很多数学方面的东西需要学习,因为这么多年来我一直逃避数学。
但现在,我的冒名顶替综合症开始消失了。我永远无法完全摆脱它,因为我仍然相信初心(初心即禅宗),但它不再让我害怕了。
感谢您的阅读,祝您一切顺利。
卢瓦克·特鲁绍
附言:如果你想深入学习前端函数式编程,与其循序渐进地学习你的语言,不如尝试学习 PureScript、ClojureScript、ReasonReact、fp-ts 或 Elm(我个人最喜欢的)。它们以 JavaScript 为目标,但会迫使你以函数式程序员的思维方式思考。
有一本关于 FP 的书籍不容错过,它比其他任何书都重要:SICP
如果您想找到一个专注、热情且乐于助人的 FP 社区,我推荐这个 FP slack 。
以下是我最喜欢的 3 个关于 FP 的播客:
- Eric Normand 的《函数式编程思考》
- 功能极客,作者 Proctor
- CoRecursive,作者:Adam Bell
我的下一篇文章将讨论进一步的资源和工具。
鏂囩珷鏉ユ簮锛�https://dev.to/ltruchot/cure-impostor-syndrome-with-function-programming-3ih6