在与 Nathan、Max 和 Antonio (Zed 的三位联合创始人) 上次对话之后,我仍然有很多问题要问:你们为什么做出这样的技术选择? Rust 对 Zed 有多重要?你们是否刻意地像现在这样掌握技术栈?你们如何决定要打磨和永久构建什么,以及更快地交付什么?
幸运的是,他们再次和我坐下来,再次回答了我的问题。
以下是我们一个小时对话的编辑版记录。 我试图尽可能地保留意图和意义,同时消除那些嗯、喜欢、你知道之类的词语,以及构成深入对话的停顿和更正。
(您可以在我们的 YouTube 频道上观看完整的对话。)
Thorsten:你们三个人一起工作多久了? 有 10 年了吗?
Nathan:Ungefähr. [德语,意为:“差不多。”]
Max:是的,差不多。
Antonio:我想 10 年听起来差不多。 2014 年,是的。
Thorsten:Atom — 那是 10 年前的事了。 你们一起在 Atom 上工作,然后说“我们要构建 Zed。” 很明显,你们对想要构建的东西有一个愿景。而且你们也做出了非常明确的技术选择。你们使用 Rust,它是 GPU 加速的,CRDT。 我想知道:这些技术选择与 Zed 的愿景有多大关系? 技术扮演了多大的角色?
Nathan:我的意思是,在我看来,Zed 的愿景只是 Atom 最初愿景的更精致和更充实的版本,由于我们所做的技术选择以及我认为我们所有人开始使用 Atom 时的技术成熟度,Atom 的最初愿景未能实现。
但我一直以来的目标都是一个轻量级的编辑器,它是我喜欢使用的最小化编辑器,感觉像一个文本编辑器,但在需要时具有 IDE 的强大功能,而没有体验中的所有缓慢和 UI 中的那种沉重感,但仍然很强大。 这是我早期想要的东西。 并且它是可扩展的。
你知道,我记得使用 Emacs 时,觉得可以扩展它很酷,但你有点像在字符级别上操作。 因此,这也是最初愿景的一部分,现在 Max 通过 Tree-sitter 实现了这一点。 你知道,基本上是可脚本化。 我们现在还不能脚本化,但我们会实现的。 但是当我们实现时,我们将能够访问比仅仅循环字符或我在 Emacs 中所做的事情更丰富的文本表示。 我的意思是,他们现在可能也拥有了,对吧? 因为 Max 写了 tree-sitter。
Max:我听说他们有。
Nathan:所以这很酷。 但无论如何,这都是愿景的一部分。 而且在 Atom 中并没有实现。 我的意思是,当 Chris 聘请我从事 Atom 工作时,我几乎没有加入[意思是:加入 GitHub 来从事 Atom 工作],因为我害怕使用 Web 技术,而且它无法实现。
但老实说,我不知道当时我拥有的任何东西是否会让我们做得更好,因为当时 Rust 并不存在。 所以它应该是 C、C++。 我不知道,在当时我们创建 Atom 时,用原生语言做一些事情真的很难。 我认为我在基本算法等方面的技能还没有到位,这对文本编辑至关重要。 C++ 真的会减慢我在那里的学习速度。 所以我认为事情的发生方式是它需要发生的方式。
我们在 Atom 中达到了某个点。 那是 2017 年,当我们发布了 Teletype 时,感觉就像,好吧,不再是我们的无知阻碍了我们,而真正是平台阻碍了我们。 这就是它开始给人的感觉。 仅仅是因为在 JavaScript 中,JavaScript 中的数组是... 你认为你有一个对象数组,但你实际上有一个指向对象的指针数组。 所以每次你走过它时,你都在追逐它。 你无法控制内存。 垃圾收集器会暂停,你无法控制。 你只需查看该死的配置文件。
Thorsten:当你在 Atom 上工作时,有没有一个特定的时刻你认为“哦,我希望我们用 X 来构建它”? 还是纸张划痕的积累? Antonio 现在在点头。
Antonio:说到 10 年来从事这项工作:我记得我在 Atom 中的第一个项目之一 — 我不知道你是否还记得,Nathan — 是加速行布局。 基本上,我们看到行布局非常慢。 我记得尝试在 iframe 中渲染行。 我记得使用 Canvas,测量文本,以及所有这些 API…… 我不知道,Canvas API 与浏览器 API 不完全相同,所以你无法正确测量文本。 iframe 的东西有一些其他的奇怪问题。
我在 Atom 中的经历总是感觉像是在向后弯腰来尝试实现一些原则上应该很简单的事情。 布局一些行,并读取光标在两个字符之间的这个位置上的位置。 这似乎从根本上是可行的,但总是感觉工具不在我们的掌握之中。 它们离我们想要做的事情还很远。
Nathan:那是一场噩梦。 我的意思是,具有讽刺意味的是,我们创建了 Electron 来创建 Atom,但我无法想象比代码编辑器更糟糕的 Electron 应用程序了,我不知道。 对于更简单的事情来说,它可能还可以,内存占用很糟糕,但还可以。 但对于代码编辑器来说,我认为你根本没有足够的控制级别来以直接的方式做这些事情。 它总是…… 后空翻。
所以在 2017 年的某个时候,我记得我坐在那里,在我的 Atom 中的日记里写着 — 那天晚上我想:我们必须重新开始。 我们必须重新开始,这行不通,我们永远无法将其带到我们想要去的地方。 VS Code 在使其尽可能远方面做得令人钦佩。 我相信技术会有增量改进,但我只是想要更多。
所以在那个时候,它是:好吧,我们应该做什么? 我一直在关注 Rust,我看到了一些 Raph Levien 关于 Rust 的文章。 当时,这似乎是克服其中一些障碍的唯一可行途径。 它是这样开始的:如果我们只是用 Rust 编写这个东西的核心,并保留 Electron 作为演示层呢?
因此,我们一点一点地做出了我们选择的技术决策。 即使在构建了 UI 框架,放弃了 Electron 之后,我们也在使用 Pathfinder,它就像这个非常酷的项目,基本上可以任意演示 SVG,但它太慢了。 所以然后我想:好吧,如果我们自己做 shaders 呢? 然后去了解了有符号距离场。
这有点滑稽。 这是因为我不想解决一些更根本的问题,而是被迫这样做,因为没有任何其他选择。
我不应该说只有我,不只是我。 但这是我的观点...
Thorsten:听起来目标始终是尽可能快,尽可能轻。 你试图达到目标,但你无法使用你拥有的技术达到目标。 但后来 Rust 出现了。 你并没有一开始就说“我们需要一个 GPU 加速的编辑器”,而是从说你想要最快的编辑器开始,然后 GPU 加速是做到这一点的一种方式。 对吗?
Nathan:是的,它是:我们的计算机中有这个硬件,而不是协商 DOM 节点在给定时刻位于 DOM 中,或者所有这些废话,我们可以直接像这样,这个像素应该是什么颜色? 好的。 好的,如果我们能够对该硬件进行编程,以并行地或尽可能并行地决定屏幕上每个像素应该是什么颜色 — 如果我们想要快速,我们应该使用它。
但是你知道,我们有点不情愿地来到这里,因为我不知道如何做任何事情。
Thorsten: 现在,这个问题有点预设立场,但过去三年我一直在业余时间用 Rust 进行开发,我对它的感受很复杂。但两周前,Hacker News 上有人说 Zed 中查找所有匹配项需要一秒钟,但在 Sublime Text 中速度非常快,接近 200 毫秒。所以 Antonio 和我一起合作,他编写了代码来优化在缓冲区中搜索所有匹配项的情况。但优化的代码并不是“真正优化”的代码:它没有使用任何肮脏的技巧,没有 SIMD,或者类似的东西。它是高级代码,优化之处在于它的假设不同:不是一个接一个地在循环中执行,而是假设找到所有结果。我们发布了该版本的构建,时间从 1 秒降至 4 毫秒。
Antonio: 哈哈哈
Thorsten: 我坐在那里,看着这 4 毫秒,然后...好吧,我想:这之后午休一定会很愉快。但是 4 毫秒?使用如此高级的代码,只是调用了其他内部 API?哇。所以我想问的是:Rust 有这些零成本抽象——所以你可以使用高级别的抽象来构建文本编辑器,但它仍然给你这种性能。你认为这是 Rust 的一个特殊之处,还是你认为如果你是一个更好的 C++ 或 C 程序员,你可以在另一种语言中做到这一点?
Antonio: 你可能可以用 C 和 C++ 来做到。我不知道。我的意思是,tree-sitter 是用 C 编写的,对吧,Max? 所以用 C 编写复杂的软件库是可能的。虽然我不得不说,每次我看 tree-sitter 中的 C 代码时,我都会尖叫,因为它对我来说太多了。我不知道。
就我个人而言,是的,Rust 处于一个很好的位置。如果不是编译时间太慢——这是我真正不喜欢这门语言的一点,但也许是我们的项目太大了,我不知道。
但确实很酷,你可以建立在这些抽象之上并依赖它们。我的意思是,我不知道零成本——我认为每个抽象都有成本。
但这个项目的总体情况是... 对于 Atom,我们总是感觉不知道在哪里寻找性能。对于这个项目,对于 Zed 来说,情况更像是:我们可以做这个,我们可以做那个,我们可以改进这个。就在上周,Nathan 和我还在讨论如何改进 SumTree 的减法,以更快地执行批量插入。
Nathan: 然后你实现了它,对吧?
Antonio: 是的。但尚未发布。
Nathan: 太棒了。
Max: 我想说我们在 Atom 上做了很多 C++——我们做了很多。我们尝试了。它奏效了,但有一个非常重要的区别——很明显——JavaScript 应用程序代码和 C++ 库代码之间的界限在哪里。人们会谈论性能并说“只需在后台线程上执行此操作,不要在主线程上执行”,我们会说“好的,我们可以做到”,但这意味着涉及的整个子系统需要放入 C++ 中才能共享内存。然后围绕它构建 JavaScript API,并弄清楚它将如何仍然看起来像惯用的 JavaScript 代码,并保留它从用 JavaScript 编写时拥有的所有这些属性。
然后我们才能真正将这个任务移动到后台线程。
编写 JavaScript 代码——它是可编写脚本的、可插入的、可覆盖的——以及具有共享内存和多线程核心功能的 C++ 之间存在如此大的差异。
Nathan: Rust 被设计为多线程的。我记得当我尝试学习 Rust 时,我想实现这个 伸展树,因为伸展树是我们在 Atom 中大量使用的结构。好吧,有一段时间——至少它有它的时代。我的意思是,它实际上非常适合我们的需求,但它有父指针,它是一个非常可变的结构。
我尝试用 Rust 构建它,但该语言与我作对。我想:你甚至可以用这种语言构建任何真实的东西吗?实际上,我对此表示严重怀疑。
所以我放弃了一段时间,然后我再次尝试。这一次,我构建了一个写时复制 B 树。当我以这种方式构建它时,它使用了 Arc
,这意味着它本质上对多线程友好。
当我遵循语言和借用检查器的指示,并按照 Rust 希望我做的方式去做时,结果是:哦,太酷了。
现在我们有了一种表示 绳索 的方法——这是 Zed 中基本的文本存储结构——我们可以生成一个后台线程,它是 O(1),只是碰撞一个 Arc
将其带到后台线程并查看快照,等等。
这不仅仅是关于原生。我还认为 Rust 带来了一些创新。该语言旨在以我们在多线程和低级别上使用它的方式使用。
坦率地说,我认为我有点太像一个脚本小子了,以至于无法在 C++ 中做得很好。它总是让我很恼火:这些该死的文件,跳来跳去,所有这些神秘的规则。C++ 大师可以做我们在 Rust 中所做的事情吗?可能,但我不会成为那个人。
Thorsten: 所以 Antonio,你刚刚提到用 JavaScript,你不知道在哪里寻找性能。Max,你说,当你使用 C++ 或 JavaScript 时,当你想要异步执行某些操作时,你会感觉到这些界限。现在我们听说了 Rust——你可以突然在后台线程上异步执行操作,你的限制更少,你可以自由移动。
这让我想起你在 Zed 代码库中实际可以看到的东西:你拥有整个堆栈。从 tree-sitter 进行解析到 GPUI,GPU 加速的 UI 框架——代码库中没有很多第三方依赖项。一些库,但不是大的构建块。
这对你来说有多重要?我们拥有完整的堆栈,从上到下,我们从上到下都了解它。这是一个有意识的选择,还是因为 Max 构建了 tree-sitter,然后你做了这个,现在看看我们,我们重建了整个东西而偶然发生的?
Max: 我不知道。我认为它有利弊,但到目前为止,能够简单地...决定我们希望事物如何工作非常好。就像现在:我们希望拥有使用 WASM 的语言扩展。Tree-sitter 没有这个,但我们添加了它。
有无数类似的事情。我们不想受限于某些可能无法按照我们想要的方式渲染文本的 UI 框架,因为我们是一个文本编辑器,这非常重要。但我们现在可以去改变它。
感觉好像没有什么事情是被禁止的。
Nathan: 我想说一件事:这很大程度上受到了我职业生涯早期使用 jQuery 的经验的影响。jQuery 当时很流行,我学会了 jQuery。我记得 Yehuda 来到 Pivotal 并展示 jQuery,我认为这太酷了。我被它震撼了。所以早期,所有 Atom 代码,信不信由你,都是 jQuery。
但有趣的是,学了 jQuery 之后,因为每个人都告诉我,“哦,你使用 jQuery 的原因是它抽象了浏览器 API 中的所有差异”,等等。我从来没有真正质疑过这一点。但我记得有一天,我只是坐下来阅读了该死的 DOM API。我想:你知道吗,这实际上很好。也许缺少一些功能或其他东西——我不想贬低 jQuery,我认为它有它的作用——但我得出的结论是,如果我没有一个几乎 100% 满足我需求的抽象,那么我可能不想拥有该抽象,而是进入下一层,完全理解它,并做我需要做的事情。
这有点像我们开始使用 GPUI 时发生的事情。在 2019 年,有一些 UI 框架正在开发中,但没有一个能做我知道我们需要做的事情。我不理解它们。
但我知道我可以很容易地理解我们将要依赖的基本原语——语言、图形框架。我知道我们可以学习这些东西,我知道我们已经编写了很多代码。如果我可以构建一个我可以理解并从中学习的系统,那么我知道我可以做我们需要做的事情,如果它在底层系统上从根本上是可行的。所以实际上——至少对于 GPUI——这是一个生存策略:我需要理解这一点,而理解它的最佳方法是构建它。
Thorsten: 这样做有什么缺点? Max,你说有权衡。
Nathan: 需要永远的时间。它很慢。
Antonio & Max: [笑声]
Antonio: 让人们上手也很棘手。你没有使用大家都知道的 X 框架,你必须从头开始教授这个代码库——你知道,30 万行代码。这是一个缺点。
但很酷的是,虽然这是一个缺点,但与此同时,还有其他人编写了该代码,并且可以向新人解释它。
它可能更慢,但同样,你保留了控制权。
Nathan: 我认为它会累积。优点会累积,而缺点会贬值。有人刚刚在 GPUI 上构建了另一个应用程序,所以现在我们有了另一个利益相关者。拥有它的成本,我们将随着时间的推移逐渐注销,而拥有它的成本和好处将开始发挥作用。
Thorsten: 有时人们会说:我只构建一次,然后我再也不需要碰它了。与此相反的是:你无法预测未来,够用就好,等等。
你刚才说自己构建所有东西会更慢,这给人一种“构建一次,并为我们的用例做正确的事情”的感觉:只有适合我们想要做的事情的完美抽象。与此同时,你们都有这种紧迫感。我的意思是,我四周前加入,我确实觉得我们进展很快,而且我们有很多事情要做。
你如何平衡这一点?你如何对你想要构建的东西有一个宏伟的愿景,并将其与“我要编写着色器,我要完善我们如何渲染阴影或任何东西”相平衡?
Nathan: 构建你需要的,只构建你需要的,不多也不少,并在合理的范围内尽可能好地构建它。然后,当它结果证明不完全是你所需要的时,愿意在你学习之后重新审视它。但我认为,如果你有意识地、谨慎地进行每一次笔触,并且不浪费时间猜测你可能需要什么,那么……对我来说,这总是奏效的。有时候需要一段时间。
Antonio:我想补充一点:这是一个渐变的过程。不是所有东西都需要完美构建。或者至少这是我对我们编写的大部分代码的看法。如果我们在 GPUI 中编写东西,那么整个应用程序都依赖于 GPUI,那最好是完美的。或者像 SumTree 这样的数据结构,它在代码库中被广泛使用。这个数据结构我们真的想要做到完美,因为它必须很快。
它必须完美地工作,这样我们才能在其基础上构建,对吧?这也反映在我们对这些东西进行的测试中。SumTree 经过了随机测试,因为我们想要确保所有这些边缘情况都能完美工作。
现在,当你向边缘移动时——Thorsten 你提到的那种性能提升,我们没有花三个小时来镀金,对吧?就像:只要能完成工作就好,它几乎就在边缘。我的意思是,我们应该对代码感到满意,我们应该始终努力编写尽可能好的代码,但我们不需要过度追求完美。
这是一个渐变的过程。越核心的东西,就越值得思考和高质量。
Nathan:我最喜欢的代码是那些我通过努力赢得编写资格的代码。哇,好多同音异义词。
使用 GPUI 编写代码让我非常开心,我几乎感到内疚。但我有资格编写这段代码,因为我编写了第一个版本,我与它共存,我推动了它前进,我在需要做出妥协的时候做出了妥协,以使事情正确。
但现在是我们能让它变得更好的时候了。并且现在改进它是合理的。而且我是知情的。我认为很多时候人们谈论重写——如果你正在重写别人写的东西,要加倍警惕自己。
但如果你写了它,你与它共存,并且你付出了努力……这也值得一提:不要让完美主义妨碍学习。
Thorsten:如果要把你们三个人……我不知道有什么东西是你们无法构建的,但假设你们必须构建,我不知道什么——一个用于飞机的 PID 控制器。飞机软件,就是这样。类似的东西。
Nathan:核反应堆控制子系统。
Thorsten:你不知道这个领域,你还不知道你要如何构建它,你也不知道你需要哪些部分。你是否认为在这种情况下需要一种不同的方法?不像在编辑器中,你对你想要的东西有强烈的愿景,你之前构建过一些,所以现在你知道哪些部分重要。你事先知道,GPUI 将会很重要。所以让我们花时间在这上面,像 Antonio 说的那样,把它镀金。
Max:我的意思是,我不知道核反应堆是不是一个好例子,但我确实觉得如果这是我们的第一个代码编辑器……我们确实“差即是好”。它不是故意写得很糟糕,但我们采取了一种更快、更脏的方法,然后识别出那些真正难以在其基础上构建的痛点,以“差即是好”的形式存在。
但我确实认为,如果由于某种原因 Antonio 和我和 Nathan 必须构建一个……
Nathan:选择一些不那么关键的任务怎么样?
Max:……一个 Shopify 克隆版之类的。我们可能会有不同的心态。我们不会知道哪些部分需要真正高度磨练。
Nathan:但如果我真的要构建一个核反应堆控制系统,我会使用拜占庭容错共识算法,并让三个团队相互对抗,以破坏彼此的安全性,然后让他们就所有事情达成共识。但我不知道如何做到这一点。
Antonio:还有另一个例子,它不像核反应堆那样关键,但在那里我们不知道数据结构,并且我们花时间学习了它。为 Atom 和现在的 Zed 中的缓冲区提供支持的结构并非一直都是 CRDT。有一个研究阶段,Nathan 和我阅读了……我不记得有多少论文了。很多。而我们现在使用的 CRDT 方法——我们仍然重写了两三次——但该方法或多或少是相同的。
所以我认为这部分来自于经验。我觉得你倾向于培养一种感觉,知道你需要花时间在什么地方,以及什么地方是更不重要、更不必要的。
也就是说,我们确实重写了 CRDT 两三次,但研究部分很重要。我不知道。
Nathan:有趣的是,在发布的 Atom 中,缓冲区是一个行数组,一个 JavaScript 字符串数组。而在 Zed 中,它是一个多线程友好的、可快照的、写时复制的 B 树,它索引你可以想象的一切。或者说我们需要的。所以我们做到了差即是好。
但是重新开始,它还会是一个行数组吗?可能不会,因为看看它的时间复杂度。并多加一些思考,但——再说一遍——我是通过“差即是好”并让它在最终重要的边缘情况下变得非常缓慢或有问题来学习到的。
Thorsten:Zed 中最镀金的部分是什么?
Nathan:我认为 GPUI 相当镀金,因为我们刚刚重写了整个该死的东西。
Antonio:好问题。
Max:我认为在 editor
crate 中的内容,其中有一系列不同的转换,将缓冲区的原始文本转换为你在屏幕上看到的行,展开制表符,进行软换行,插入块装饰并处理折叠等等。所有这些层都有这种统一的测试策略,即使用属性测试进行随机测试。所以我认为它们相当镀金。
多缓冲区也是,我们将不同缓冲区的不同摘录编织在一起。
Nathan:我会称它们为……我只是想为代码库的那个部分建议一种替代物质。我会说它被涂上并覆盖着鲜血。
Antonio:哈!鲜血镀层。
Thorsten:你是说编辑器和多缓冲区?
Antonio:是的。
Nathan:是的。我们进行了随机测试,在 2021 年的很多天里,我们花了整整一天的时间来调试这些随机测试中的失败,这些测试会发现这种华丽的——我的意思是,我不会说它华丽,但它很复杂——屏幕上呈现所需的不同转换层的堆叠中的一些奇怪的边缘情况。所以这只是辛勤工作,对吧?找到边缘情况,然后通过减少日志来弄清楚它们为什么会发生,而长期以来我们都是手动完成的。
Thorsten:当这些错误弹出时,你感觉如何?当属性测试抛出一个错误在你脸上,你认为“也许整个东西都无法工作?”的时候,你是否感到恐慌?或者你觉得“好吧,这只是另一件需要磨练的东西,如果不行,我们就重写它”?
Antonio:永远不要恐慌,这是随机测试的规则,永远不要恐慌。我非常相信我们作为工程师的能力,真的,也许我们必须重写整个东西,而随机测试正在告诉我们这一点,但这没关系,我们只是学到了一些东西,回到绘图板并重新做。
Nathan:可怕的是:这需要多长时间?我认为我们的种子投资人 Lee 也在某些时候问过我们这个问题。但他支持我们并保持耐心,因为它花了一段时间。
但是那部分是用 Rust 编写的。如果我们搞砸了,程序就会崩溃。再见,嗖的一声。这不仅仅是在编辑器的某个角落抛出一个堆栈跟踪之类的,不,它完蛋了。
所以我们知道让这些层正确是多么困难。而且我们知道别无选择,只能让它们正确。但是,是的,我记得,Antonio,还记得我们遇到的软换行的问题吗,我们意识到我们需要的原语是这种表示补丁的能力,然后能够将这些补丁组合在一起——那一刻我有点冒汗,心想“我们能把它弄清楚吗?”然后 Antonio 把它弄清楚了。
Antonio:是的。但为所有这些提供动力——就镀金而言——再次是 SumTree。即使这样,如果我们重写它,也会有一些关于如何改进它的想法。
Nathan:我们前几天晚上还在谈论它会是多么棒。Antonio,你应用了我们谈论的一些想法:能够以更友好的流式传输方式构建所有这些层。你做了一项优化,它将在下周登陆预览版。
Antonio:是的,我仍然需要打开它的 PR……
Nathan:为了启用更多的流式输入,这样人们在打开一个大文件时不会得到零反馈,而是开始更有效地加载内容——这是否需要重写?也许吧。也许不是。我不知道。
Thorsten:关于重写或重新做一遍的想法出现的频率非常有趣。我们上次也谈到了这一点。持续学习。不是:学习,然后修复和修补。而是:我们学到了一些东西,所以现在让我们带着这种学习重新做一遍,而不是简单地贴上创可贴。它多次出现,你可以在产品中看到它。
当我们交谈时,Antonio,你会说这样的话:之前我们是这样做的,现在我们是那样做的。就在昨天,我们基本上重写了处理 macOS 的 IME 系统的部分,因为 Antonio 说:我们不能这样放任不管,我们不希望其他人陷入这个兔子洞,让我们在上面架起一座桥梁。
Nathan:很好。很高兴听到。我听说过这件事。
Thorsten: 我不知道这是否有意义,但我的最后一个问题是... 对于很多软件,比如 SaaS 企业级应用,或者 Shopify 的克隆产品,我认为大多数用户并不关心使用了什么技术,只要它能正常工作。我想知道:您认为开发者工具或编辑器的情况是否不同?所使用的技术是否更容易被用户感知到,或者用户是否更关心技术本身?
Max: 我确实认为它会影响我们能得到的贡献类型。 我们的很多用户,他们中的很多人都愿意为代码库贡献一些东西,以满足他们自己的需求。
我认为让 Zed 容易贡献是很重要的。 如果我们全部用 C++ 编写,我认为会有很多人想改变 Zed 的某些东西,但不太愿意自己做出改变。
而自从几周前开源以来,我们收到的贡献就非常多。 我认为人们喜欢它是用 Rust 编写的。 它是平易近人的。 人们可以轻松构建项目。 他们不必学习如何使用 CMake 或其他工具来构建项目,或者 Gyp。 他们可以直接使用 cargo。
而且编译器具有严格性,这使我们作为贡献的接收方,通常可以充满信心地合并代码。 我认为这真的很有帮助。
Nathan: Rust 绝对是一个优秀的工具。 它并不完美,但我喜欢它。 但是这对于人们来说重要吗? 我的意思是,我认为人们最终想要的是一个快速的编辑器。 我们可以用 brainfuck 来编写它,他们也不会在意。 但贡献的角度是绝对成立的。
Antonio: 但我仍然想谈谈性能,我只是觉得我们因为性能原因被迫以某种方式做事。 为什么我们有这个 GPU 加速的 UI 框架? 因为性能需要达到一定的水平。 我们希望我们的帧时间低于三毫秒。 我们可以将所有内容在 CPU 上栅格化,并且我们可以使用一些可以做到这一点的东西,但是,我们没有。
在某种程度上,我们将自己定位为性能编辑器,因为我们想要一个性能编辑器。 我想要一个性能编辑器。 因此,这个选择几乎... 我们几乎别无选择。
Nathan: 但是现在有了 Zig,我对 Zig 了解不多,说实话,我还没有时间去学习它,但我尊重的人对它感到兴奋。 似乎它与 Rust 在输出方面有一些相同的目标。 我不清楚它在安全性方面牺牲了什么,或者他们如何处理这些事情。 可能存在一些实用的折衷方案,它们不像 Rust 那么严格,但在实践中有效,等等。
所以我对它很感兴趣。 我很感兴趣,但就像单一语言有很多好处一样,如果这有道理的话。 服务器端是用 Rust 写的,前端是用 Rust 写的,但如果我可以用十分之一的编译时间获得 Rust 99% 的好处,那...
Thorsten: 嗯,我可以告诉你关于 Zig 的一些事情,Discord 上有一个人说他们正在用 Zig 编写一个编辑器,但是 Zig 中文本编辑器的完美名称已经被占用了:Zed。