这是一篇对Meade Kincke的采访,在采访中他和 Katrina Owen 聊到了 Rust 编译器、一个用科学色彩空间来推算啤酒颜色的图形界面(GUI),以及他的书“A Practical Guide To Rust”。
嘿,Meade。谢谢你和我们聊天。我们想找你聊,是因为你是我们 Rust 轨道上带学生最多的导师。你已经帮助了 400 多名学生。你是怎么知道 Exercism 的?
有人在 Reddit 的 Rust 版块发帖说,Exercism 的 Rust 轨道需要导师,于是我就去看了看。我很庆幸自己这么做了,因为在里面指导别人收获特别大,而且每个人都特别友善、特别感激。我和一些在 Exercism 上跟着我的学生建立了很棒的联系,我很喜欢帮助他们。
有没有什么特别的故事让你印象深刻?
有,有一个 Rust 练习特别受欢迎:勾股三元组。
这个练习里最常见的问题往往是性能。大多数人一开始都用嵌套的for循环来解决,复杂度至少是 O(n²),效率非常低。我的目标是让学生做出线性解法:O(n)。
我的做法是不断提问。我会先问他们想不想学 Rust 的迭代器方法,因为它的好处非常多,其中之一就是你能够用 Rayon 库把工作并行化。
有一位学生回答“想,请讲”之后提到,他正在学 Rust,是因为他打算把它用在嵌入式控制上,然后用它处理自己产生的海量数据。所以并行对他来说很重要。他很高兴我拿一个看似简单的练习,来讲 Rust 里更复杂、更地道的部分。
现在,多亏了 Exercism,他请我去给他一对一授课,我们还打算一起做一些实验性项目。等他让公司全面转向 Rust 之后,我还会教他的整个团队。
我真的很享受和带过的学生一起工作,也希望这件事能继续发展壮大。
我太喜欢这件事了,所以现在我主动申请成为 Rust 轨道的维护者,在幕后帮更多的忙。
人与人之间的这种连接太重要了!你是A Practical Guide to Rust的作者。这本书讲了什么,你写它的动机又是什么?
我写这本书,是为了帮别人更好地理解Rust的某些方面。这门语言的文档并不多,我觉得需要有这样的读物:既有幽默感,又能把语言的概念讲得实实在在。书里既有基础部分,也有进阶部分。我希望读者能真切地感受到这门语言在实际中的用处。它给的是真实的例子,不是假设出来的例子。
我一直知道自己会写一本书。当我在远程教一位同事用 Rust 编程时,整本书的框架自然而然就成形了。他之前完全没碰过代码,我需要把我们这些技术宅习以为常的术语和方法,用全新的、能让人理解的方式讲出来。比如讲 Rust 的所有权概念时,我用了“从图书馆借书”和“自己拥有这本书”这样的类比。
我还把自己项目BrewStillery里的例子用了进去。这样可以很清楚地看到结构体和枚举之类的东西在真实程序里是怎么运作的。它也展示了如何在真实场景里使用并行。
写这本书的时候,我就知道我希望它读起来像故事,而不只是一本参考手册。它前后是层层递进的,但各个部分又能独立成篇。这就像照着化学手册做菜和看一集 Julia Child 的“The French Chef”之间的区别。
哦,这很有意思。你的书是写给谁的,读者能从中收获什么?
它是写给任何想学 Rust 的人的。我讲解每个概念的方式有一个共同点,就是能让读者真正理解根本,而很多别的读物更偏向死记硬背。
我看到这本书收到了很多好评。你有计划出第二卷吗?
有!我当然会继续写下去,也计划出版更多卷。
除了通过指导来教学和写作,你还参与过 Rust 编译器的一些工作。能跟我讲讲吗?
当然可以!
先简单介绍一下我的工作。一个程序发挥作用的地方本质上只有两个:编译时和运行时。函数在运行时执行时,里面的一切都得重新生成、重新计算。关键的一点是,这意味着要重新分配内存,而这是我们一直想避免的。而当一个函数是常量函数时,它在程序启动时就被加载进内存。能在编译时做的事越多,程序的性能就越好。
不久前,我听说 Rust 正在实现编译期函数执行(const fn)这个想法,我非常兴奋。我特别热衷于让东西变得既高效又精确。我很喜欢const fn的一点是,等它完成之后,我们就能优雅地确定数学常数之类的东西。目前,pi是一个硬编码的值。很多人会说这已经足够精确了,但我觉得应该把可用的数值空间整个用满。有了const fn,我们就可以用莱布尼茨公式,把浮点数的空间完全填满。
我又多读了一些东西,看到一篇博客说MIRI会让const fn的稳定化容易得多。时间一天天过去,新版本发布时我却没看到任何进展。于是我联系了 Rust 团队,开始动手改编译器。
很妙的一点是,编译器本身就是用 Rust 写的。它最初用 OCaml 写,后来用 Rust 重写,这个过程叫自举。基本上,编译器会先把所有输入解析成AST,再交给高级中间表示(HIR),然后是中级中间表示(MIR),再是低级中间表示(LIR),由LLVM处理。走过这些步骤,我们就越来越接近机器码。
有一点要明白:编译器只是一个程序,只不过是一个非常复杂的程序。Rust 编译起来要花不少时间,尤其是跑完它所有的测试。所以你不能随便塞点代码进去,就说“我搞定了”。
我在编译器上做的第一项工作是关于 HIR 的。这需要大量阅读标准库(稳定版和 nightly 版),还要顺着一个个线索往下钻。我得一路递归下去,穿过编译器里每一个嵌套类型,直到把所有可能都试遍。nightly 版和编译器相关的库里,有大量嵌套类型。要一直跟住自己在追的那条线索,得高度专注。
更麻烦的是,这个编译器是由一个分布在各处的团队一起开发的,所以我们经常遇到合并冲突。
真的特别有意思。还有很多工作要做,我最近就会继续推进。
除了这些开源贡献,我知道你是一家区块链公司的 CTO。我提起区块链,想到的都是自己在 Etherium 上亏了不少钱。对你来说,区块链意味着什么?
不幸的是,区块链已经成了有史以来最火的流行词。
它远不止是伦敦金融城和华尔街借数字货币的新潮流大捞一笔。其实我们并不是一家“区块链公司”,我们Chainetix提供的是私有账本,用来安全地保护公司的数据。事实上,我们甚至不碰加密货币。Chainetix 的目标,是把我们的专业能力交到每一个具备基础编程知识的人手中。
我的工作包括从零开始规划我们的系统和基础设施,做出真正稳如磐石的东西。我选了一个叫Habitat by Chef的项目。我之所以知道它,是因为它是用 Rust 写的,而它竟然出自 Chef 这样的大公司,这很有意思。和普通的 Docker 不同,Habitat 创建的镜像能自动更新,还能做服务绑定这类很厉害的事。我也给 Habitat 的core-plans代码仓库贡献了不少东西。
你之前提到过你的项目 BrewStillery。听起来它对你很重要。能再给我们多讲讲吗?
是的,它对我来说确实很重要!
BrewStillery是一个开源的一体化啤酒、葡萄酒和烈酒工具,我用 Rust 和GTK3写的。我还加了一套漂亮又独一无二的 CSS 主题。一句话说,它就是一个面向所有酿酒者的高级计算器。
我做了几个不同的标签页,把啤酒和香槟专用的计算器分开,另外还有一个通用标签页,酿酒师、葡萄酒酿造者和蒸馏师都能用。如果你看看大多数啤酒瓶和葡萄酒瓶,上面都会标着那瓶酒的酒精百分比,也就是按体积计的酒精含量(ABV)。BrewStillery 做的其中一件事,就是算出这个 ABV。你大概能猜到,这里面有一堆很宅很酷的东西。我最得意的是计算啤酒颜色:


这两张先后对比的图,展示了输入用量之后会发生什么。我实现它的方式,之前还没人做过。另一个很棒的功能是,所有内容都会随着你输入实时计算出来。如果你想了解色彩空间那些细节,下次在会议上碰到我就来找我,我们可以边喝几杯啤酒边聊!