序言
我曾花费大量时间思考编程,阅读这本书的你可能也在思考这个问题,不过我几乎没怎么“思考自己的思维过程”(thinking about thinking)。对我来说,思维过程的概念以及我们人类如何与代码打交道很重要,但研究这些问题的学者寥寥无几。下面通过 3 个例子加以说明。
Noda Time 是一个.NET 项目,旨在为.NET 内置的日期和时间类型提供一套替代方案,而我是这个项目的主要贡献者。在我看来,Noda Time 是一个很好的平台,借此我可以集中精力设计 API,尤其是命名。我发现,有些 API 从名称上看是改变一个现有值,实际作用却是返回一个新值。注意到这类问题后,我便尝试采用一些让错误代码听起来不对劲的名称。以 LocalDate 类型定义的 PlusDays 方法(而不是 AddDays 方法)为例,想必大多数 C#程序员能发现下面这条语句错在哪里:
date.PlusDays(1);
以下语句看起来更合理:
tomorrow = today.PlusDays(1);
对比 DateTime 类型定义的 AddDays 方法:
date.AddDays(1);
尽管这条语句看起来只是在修改 date,并不是错误,但它和第一条语句一样不正确。
第二个例子也和 Noda Time 有关,不过没有那么具体。虽然许多库(有充分的理由)设法承担所有艰巨的任务而无须程序员多加思考,但我们明确希望使用 Noda Time 的程序员在编写涉及日期和时间的代码前能仔细推敲。我们努力使程序员思考自己真正希望实现的目标,不能有半点儿含糊,然后通过代码把这些目标尽量清楚地表达出来。
最后来看一个概念性的例子:Java 和 C#的变量存储的值,以及向方法传递参数时会出现哪些情况。我似乎大半辈子(我算了算时间,差不多就是这么久)都在声讨 Java中通过引用来传递对象的概念。25 年来,我想自己一直在努力帮助其他程序员调整他们的心智模型。
事实证明,程序员的思维方式对我来说很重要,但因为缺乏对认知科学的深入了解,我只能依靠猜测和来之不易的经验。虽然我并非初次接触这方面的知识,但这本书仍然能够助我一臂之力。
在奥斯陆举行的 2017 年挪威开发者大会上,我第一次见到了费莉安·赫尔曼斯本人,当时她做了题为“编程即写作,写作即编程”(Programming Is Writing Is Programming)的演讲。我发的推文说明了一切:“我需要很长时间来消化全部内容,不过演讲令人拍案叫绝。”我至少聆听过 3 次赫尔曼斯所做的这个演讲(当然,演讲内容随着时间的推移在不断变化),每次都有新的收获。最后要指出的是,可以从认知层面来解释我一直想做的某些事情——我也会遇到一些促使我不得不调整方法的意外情况。
阅读这本书时,你可能会不断发出“啊,这就说得通了!”或者“哦,我没想到!”这样的感叹。除了一些立竿见影的实用建议(例如使用抽认卡),我认为这本书会产生潜移默化的影响。也许是何时在代码里加入空行要多加斟酌;也许是调整分配给团队新成员的任务,甚至只是调整完成这些任务的时间;也许是我们在信息技术问答平台 Stack Overflow 上解释概念的方式。
无论这本书能产生哪些影响,赫尔曼斯的工作都为程序员提供了一个思想百宝箱,帮助他们了解工作记忆如何思考和加工信息,然后转移到长时记忆——思考自己的思维过程令人欲罢不能!
——Jon Skeet1 谷歌资深开发者关系工程师
1广受赞誉的程序设计专家,人称“编程界的李小龙”。他是 Stack Overflow 技术社区最有影响力的专家。——编者注