HackerTube English?
软件边界与变化 →

旧用户还在,新版本能改到哪一步?

一个必填字段、一段旧网页、一台苏联计算机:版本一旦有人在用,修改就要回答谁来迁移、谁来承担旧行为。

本文的问题 · 8
  1. 老程序还能启动,算兼容了吗?
  2. 一次必填字段变更,谁来搬家?
  3. 一段旧网页让新的语言设计背上什么义务?
  4. 客户愿意为定制付费,谁能负担下一次升级?
  5. 软件兼容能省下重写的时间,也会要求谁跟上?
  6. 菜单应该报告用途,还是命令全局输入?
  7. 把实现藏起来,后来者还接得住吗?
  8. 模块发布以后,别人怎样接出作者没计划过的用法?

老程序还能启动,算兼容了吗?

把消息字段改名,服务自身的代码完全可以一起编译通过。Hickey 提醒你注意,越过进程边界的名字已经有别的读者。Goetz 则区分旧二进制能否链接、源代码能否重编,以及运行后行为是否一致。检查一次改动时可各保留一份旧制品、旧源码和旧消息,分别试;同一个「兼容」复选框装不下这三种实验。

原文与时间戳 · 2
as your names start escaping out of your processes, that they are global names
The Language of the System - Rich Hickey · ▶ 21:29–24:03 · 段落范围
existing class files will continue to link
Brian Goetz - Stewardship: the Sobering Parts · ▶ 20:53–20:59

一次必填字段变更,谁来搬家?

按照 Hickey 的提问方式,加必填字段是提高了调用者必须满足的门槛。Winters 的菱形依赖解释了为什么两支团队不能随时一起搬:它们可能经由不同中间库依赖同一组件。Wright 给出实际顺序,先在保留旧默认行为的条件下提供新接口,逐批迁移调用点,最后结束过渡。版本号可以指认两个版本,却不能替尚未迁完的那一支提供数据。

原文与时间戳 · 3
if you require more than somebody who's giving less now is not going to get what they want
Spec-ulation Keynote - Rich Hickey · ▶ 24:55–25:05
If everyone in your infrastructure doesn't upgrade at the same time, then we have version skew.
CppCon 2017: Titus Winters “C++ as a "Live at Head" Language” · ▶ 15:30–15:36
Usually you add the new thing without making it the default.
CppCon 2018:H. Wright “Large-Scale Changes at Google: Lessons Learned From 5 Yrs of Mass Migrations” · ▶ 13:15–13:19

一段旧网页让新的语言设计背上什么义务?

Eich 解释 JavaScript 为何要保留一些当初没想清楚的行为:别人已经把它写进网页。Van Rossum 回忆的 Python 注解提供另一条迁移路径,在既有语法里表达给外部检查器的信息。Lattner 谈 Mojo 时则把采用类型设计成逐处选择。拿一个没有类型标注的旧函数来试,分别问三个问题:运行结果要不要一样,谁会读取新信息,没迁移的调用者还能不能工作?三种语言承担的兼容义务各不相同。

原文与时间戳 · 4
the force of web compatibility meant early mistakes couldn't be fixed
Brendan Eich: JavaScript, Firefox, Mozilla, and Brave | Lex Fridman Podcast #160 · ▶ 18:48–18:55
a compromise syntax
Guido van Rossum: Python and the Future of Programming | Lex Fridman Podcast #341 · ▶ 84:58–85:04
use that existing dummy syntax
Guido van Rossum: Python and the Future of Programming | Lex Fridman Podcast #341 · ▶ 85:50–85:54
progressively adopt types into your program
Chris Lattner: Future of Programming and AI | Lex Fridman Podcast #381 · ▶ 32:43–32:46

客户愿意为定制付费,谁能负担下一次升级?

讲日本软件业的案例里,适配一家客户的业务流程可以赢得合同,却未必留下其他客户能直接采用的产品。共同平台缺失时,后续升级也会被分摊到许多独立实现里。估算一次定制的价值,除了一张当期合同,可以再追踪由谁维护差异,以及第二个客户能复用多少经过检验的行为。

原文与时间戳 · 2
modified for customers' existing business practices
Why is Japan So Weak in Software? · ▶ 5:48–5:53
there was no widely accepted platform or operating system
Why is Japan So Weak in Software? · ▶ 11:59–12:08

软件兼容能省下重写的时间,也会要求谁跟上?

苏联计算机方案评估中,兼容既有软件、学习开发方法和更早交付并未始终指向同一路线。列出兼容目标后,再沿时间轴追一轮:现有程序今日能否运行,下一版操作系统出来时需要哪些文档与技能,本地团队又要等哪个供应者?这能把「兼容」从单个勾选框展开成可检查的维护承诺。

原文与时间戳 · 2
compatibility, learn British programming methods
Why the Soviet Computer Failed · ▶ 15:17–15:22
push back the project's delivery date
Why the Soviet Computer Failed · ▶ 15:23–15:28

菜单应该报告用途,还是命令全局输入?

Stone 给接口承诺加了一道具体检查。打开菜单时,应用到底是在说「这是由这次点击触发的弹出菜单」,还是要求「把全部输入给我,并把窗口放在这里」?他在 2013 年演讲中用音量键和屏保冲突说明后一种约定怎样把局部需求扩散到整个桌面。设备枚举给出同一边界的另一例子:当前设备与后来热插拔的设备使用同一种事件格式,调用者就能用同一段逻辑处理。检查自己的接口时,可以列出调用方真正知道的意图,以及应由拥有全局状态的一方协调的动作;这比只问参数数量少不少更接近职责划分。

原文与时间戳 · 2
Wayland is also descriptive, not prescriptive.
The Real Story Behind Wayland and X - Daniel Stone (linux.conf.au 2013) · ▶ 31:35–31:39
these are all the current devices in the same format
The Real Story Behind Wayland and X - Daniel Stone (linux.conf.au 2013) · ▶ 34:38–34:42

把实现藏起来,后来者还接得住吗?

Blow 给「隐藏实现」加了一项维护问题:今天一个人能掌握的复杂度,是否也能交给后来接手的人?他担心的不是每位调用者都必须懂全部底层,而是团队把排错诀窍当作常识后,真正理解机制的人可能逐渐变少。沿着这个问题检查模块,可以同时记录接口答应什么、谁能够解释其实现,以及换人后怎样检验维护能力。这是从演讲引出的检查方法,不是关于某个工具或整个行业必然衰退的结论。问答中的保留也要一起带上:问题本来就可能很难,减少附加复杂度不等于保证人人都能完全理解它。

原文与时间戳 · 2
the amount of complexity we can sustain over time
Preventing the Collapse of Civilization / Jonathan Blow (Thekla, Inc) · ▶ 47:56–48:01
whether that's good enough I don't know
Preventing the Collapse of Civilization / Jonathan Blow (Thekla, Inc) · ▶ 62:30–62:37

模块发布以后,别人怎样接出作者没计划过的用法?

Ken Thompson 回忆,Unix 管道让原先各自工作的程序能串在一起。要让排序工具成为过滤器,输出里还得去掉工作进度之类的杂讯,才能直接交给下一道程序。Stefan Karpinski 用 Julia 说明另一种接法。下游可以在自己的包里给已有类型定义新方法,让不同包继续共用该类型。前一个例子把接合点放在程序之间传递的数据上,后一个把接合点放在共用类型和可追加的方法上。评估一项扩展时,可以具体问,下游需要哪些稳定约定,才能在自己的代码里把它做出来?

原文与时间戳 · 2
interconnections of things that were never meant to be in the same room together
VCF East: Ken Thompson interviewed by Brian Kernighan · ▶ 34:48–34:58
can define methods outside of the type later on
The Unreasonable Effectiveness of Multiple Dispatch | Stefan Karpinski | JuliaCon 2019 · ▶ 24:03–24:09

读完再想一步

挑一个你想改的接口:列出仍依赖旧行为的用户,再写下谁为迁移付出时间。