夜天之书

A modern wizard.

近几年,国内开源项目捐赠到 Apache 软件基金会(ASF)的案例很有一些。几乎每个在进入孵化器和从孵化器当中毕业时发通稿的项目,都会选择在标题中加入“全票通过”的字样。

诚然,大部分项目在 ASF 孵化器中茁壮成长,实际上投票结果也是没有反对票,使用这一标题无可非议。然而,对于把同侪社群(Community of Peers)作为社群核心价值之一的 ASF 来说,追求全票通过并不是必须的。

在 ASF 孵化器当中,近些年来由于孵化器主席 Justin Mclean 个人风格的原因,许多项目遭受了无端的审查压力。我认为有必要在国内营造出人人都可以,甚至都应该“全票通过”的氛围时,阐明 ASF 同侪社群的理念和工作方式,以减少项目在面临不合理的挑战时遭受的挫败,尤其是当它来自于某个看起来权威的成员时。

阅读全文 »

随着 Apache 软件基金会(ASF)在国内的深入发展,越来越多的项目希望藉由进入 ASF 孵化器孵化,来建设开源社群。在进入孵化器之前,项目发起人或其核心团队必须撰写一份孵化器提案来介绍项目的基本情况,以供孵化器项目管理委员会(Incubator Project Management Committee, IPMC)评估是否适合孵化。

ASF 孵化器成立于 2002 年,至今已有超过 20 年历史。截至本文写作时,孵化器一共孵化了 347 个项目,其中 241 个项目已毕业,28 个项目正在孵化中。

ASF 孵化器的官网有丰富的文档介绍如何进入孵化器以及按照 The Apache Way 建设开源社群。对于孵化项目而言,最核心的两份文档是:

此外,进入孵化器前需要撰写的提案,孵化器也提供了相应的模板,过往的孵化提案都是公开可查的,这也是撰写孵化提案时的重要参考。ALC Beijing 整理翻译了这份材料,可以阅读其发布文章《ASF 新孵化项目提案指导》

本文从我至今指导孵化五六个项目的经历出发,讨论项目在进入孵化器前撰写提案时经常遇到的问题以及应对方法。

阅读全文 »

本文承接《Zig 中间表示》的内容,继续讨论 Zig 程序编译的下一步:从 ZIR 指令序列,经过语义分析的过程,生成 AIR 指令序列。

本文翻译自 Mitchell Hashimoto 关于 Zig 的系列博客第四篇:

语义分析是 Zig 程序编译的核心环节,且它包括了 Zig 语言独特的设计:编译时求值。不同于其他语言常常需要使用额外的语法来定义和计算类型(泛型),Zig 采用编译时求值的方式来完成类型计算。这使得很多原本需要宏或者模板的逻辑,现在可以使用跟主语言相同的语法来编写代码完成。

我在推特上发文讲过:

Zig 的泛型是用编译时类型计算来实现的。这有一个挺有趣的提示:如果 Zig 的编码体验提升,很多类型计算方法(类型论的实现)可以作为 Zig 库来提供,而不用像之前一样嵌入到编译器里作为编译器的内部实现。这可能是一个开放编译时计算的方向。

本文讨论了 AIR 制导生成的主要流程,但是没有深入讨论编译时求值的细节,也没有包括变量活性分析的内容,比较可惜。

以下原文。

阅读全文 »

本文承接《Zig 词法分析和语法解析》的内容,继续讨论 Zig 程序编译的下一步:从抽象语法树(AST)中生成中间表示(IR)。

本文翻译自 Mitchell Hashimoto 关于 Zig 的系列博客第三篇:

翻译本文的过程中,我越来越回想起自己使用 Perl 6 做编译实习作业的时候。通过 Perl 6 内嵌的 Grammar 语法,我基本把词法分析和语法分析的内容给快速解决了。余下的大部分时间都在完成从 AST 到课程定义的中间表示的翻译,数据流分析和生成 riscv 汇编代码的工作。应该说,北京大学仿照虎书内容做的编译实习课程还是很有含金量的。

感兴趣的读者可以查看我当时的代码仓库,其中包括一个完整的 PDF 报告。

以下原文。

阅读全文 »

Zig 语言是近几年来逐渐声名鹊起的一个新编程语言,也是数目稀少的系统编程语言家族中的一个新成员。它由 Andrew Kelley 于 2015 年开始创造,至今已经开发了八个年头,但是仍然还未发布 1.0 版本。

不过,已经有不少新锐项目选择使用 Zig 开发,例如 JavaScript 运行时和完整开发套件 bun 和分布式金融数据库 tigerbeetle 等。

Hashicorp 的创始人 Mitchell Hashimoto 也在前年卸任 CEO 成为 IC 后开始投入大量时间开发 Zig 程序,包括开源的 libxev 库和目前尚未公开的 Ghostty 等等。

Mitchell 在开发 Zig 程序的过程中,撰写了系列博客介绍 Zig 程序的编译过程。这些内容有助于理解 Zig 语言的设计,以及它如何在 LLVM 提供的抽象和系统开发者之间建立起一层抽象。

我在取得 Mitchell 的同意后对这些文章做一个翻译,以飨读者。

本文翻译自系列第一篇和第二篇博客:

这一部分属于编译器的前端,相对而言比较简单。

以下原文。

阅读全文 »

上周,我收到清华大学出版社编辑寄来的新书《流计算系统图解》。趁着周末的功夫,我快速浏览了本书的主要内容。一句话评价:值得一读,尤其是对开始开发流计算任务或系统一到两年,初步实现过一些功能或作业,但是还没有对流式系统建立起系统认识的开发者。

cover

阅读全文 »

上一篇文章《Rust 社群何以走到今天?》发布之后,得益于 Rust 社群的繁荣和成员的分享惯例,我收到了不少关于 Rust 现状的评论。

大部分评论集中在 Rust 项目社群的治理上,即 BDFL 和基金会会对 Rust 项目社群产生什么影响,以及 Rust 项目社群是否需要 Leadership 组织。

阅读全文 »

本文有些标题党,实际想讲的内容,是我从部分 Rust 曾经的核心开发者的自述当中,所发现的 Rust 项目社群开源协同模式发展至今的一些特点。

我会从这些自述发言的内容切入和展开,对比其他社群遇到相似挑战的状况和应对方式,讨论 Rust 项目社群在协同方式维度上走到今天的沿革。

阅读全文 »

昨天的文章里,我介绍了 Async Rust 当前的实现以及一个实现 Async Runtime 需要了解的概念和现有的一些实践。

文章发出后,有评论称 Async Rust 创造性工作,没有可借鉴的经验。诚然,Rust 系统编程语言的定位就决定了它与其他有运行时的语言在设计时存在巨大的不同,同类语言 C 和 C++ 在异步编程方面,受限于语言的历史包袱,相关的支持往往以三方库而不是语言级的支持出现。

不过,Rust 至少可以借鉴自己一路走来的经验。Async Rust 的主要开发者之一 @withoutboats 在今年十月份的时候写了一篇 Why Async Rust 的博文,介绍了 Async Rust 一路发展的沿革和背后的设计决策。也是这一篇文章,帮助我理解了大量 Async Rust 设计的理由,从而融会贯通地写出昨天的文章。

随着软件系统越来越复杂,一个完整的复杂软件动辄几十上百万、甚至上千万行代码,提交记录少说几千,动辄几万甚至几十万。个人再也很难有足够的时间,单纯依靠读源代码和提交历史来理解系统运行的机制。这个时候,设计文档和作者现身说法讨论设计过程,尤其是失败的设计过程,就显得尤为重要。

实际上,我认为国内软件行业前沿的水平已经能跟世界前沿竞争,差的是时间积累的底蕴和人才的绝对数量。例如,全球第一波做数据库的人,到现在几乎都是三五十年经验起步,他们通过师父带徒弟甚至带出徒孙的形式,培养出了一大批领域专业人才。这一壁垒是很难走旁门左道超越的。

所幸开源运动的发展使得我们能够无国界的接触最前沿的软件设计思想和技术实践,我们于是可以对照一个完全开放的软件系统,根据核心开源开发者的介绍,理解这些智慧和经验的结晶。

以下原文,文中的“我”是 @withoutboats 的自称。

阅读全文 »

绝大多数第一次接触 Async Rust 的开发者所写的 Hello World 程序是下面这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
async fn say_world() {
println!("world");
}

#[tokio::main]
async fn main() {
// Calling `say_world()` does not execute the body of `say_world()`.
let op = say_world();
// This println! comes first
println!("hello");
// Calling `.await` on `op` starts executing `say_world`.
op.await;
}

目前最流行的 Rust Async Runtime tokio 告诉你,只要在 main 函数前加上 #[tokio::main] 这个咒语,再把 main 函数定义成一个 async fn 函数,就可以在程序的任何地方用 async fn.await 语法享受到并发编程的免费午餐了。

但是,这样的解释显然不足以满足相信 Rust 尽可能显式表达所有开销的哲学的人;也就是说,到底 async fn 里的逻辑是怎么被执行的,代码中出现 .await 的时候,Rust 程序实际在执行什么动作。

本文基于具体的异步运行时和并发库代码,介绍支持 Rust 并发模型工作的核心概念。

阅读全文 »
0%