图形计算器始于 1985 年,用于 128K Macintosh 的 C 语言,当时是 16 位整数、黑白 Quickdraw 和 8 MHz 68000 CPU,没有 MMU、FPU 和 GPU。这是一个更简单的时代。从那以后很多事情改变了。

我长期以来一直坚持“如果它没有坏,就不要修复它”的理念,因此代码带有许多过去的痕迹——在当时有意义的设计选择,但不再适用。它见证了 CPU 从 Motorola 68K 到 IBM PowerPC 系列、Intel 和 ARM 的变化。它最初是用 Inside Macintosh 的经典 Mac API 编写的,然后是 Carbon,然后是 Cocoa、AppKit 和 UIKit,现在是 SwiftUI。
编写新代码添加新功能并将古老的遗留代码隐藏在抽象层下更容易。最终,数十年积累的技术债务使新的发展变得令人担忧。Graphing Calculator 仍然使用 Classic Mac OS 9 协作线程 API 来运行 1980 年代冻结的非线程安全代码。从头开始重写所有内容,也就是从轨道上起飞和核对整个站点,几乎从来都不是一个好主意。遗留代码体现了当前开发人员从未经历过的数十年艰苦学习的经验,即使是原始开发人员,如果他们还在的话,也早就忘记了。虽然一个新的开始可能在美学上令人满意,但它为错误创造了巨大的表面积。在典型的 dot 版本中,专注于新功能的测试很容易。完全重写后,一切都是新的。
C++ 一直是管理大型项目复杂性的有效语言,那么我为什么要更改语言呢?Apple 的增强现实技术给我留下了非常深刻的印象。在我们的 iOS 产品中添加了 AR 支持后,我构建了一个原型应用程序,探索如何在数学教育中使用 AR,灵感来自于儿童故事书中对 AR 的使用。 该应用程序主要是 C++ 和 ObjectiveC++。该原型使用 ARKit 进行视觉和机器学习,这在 Objective-C 中是可行的,但在 Swift 中会更容易。很明显,新的 Apple 技术将继续如此。
我通过移植 Graphing Calculator 的核心计算机代数系统来学习 Swift。它开始是一个学习练习,然后变成了一项可行性研究。大流行在该决定中发挥了作用,因为这成为了我的大流行就地避难所项目。重构可以在 C++ 和 Objective-C++ 中完成,但它不会那么有效,也不会那么有趣。该移植合并了许多转换:
从 | 至 |
C++/ObjC/ObjC++ | 迅速 |
lex/YACC | 迅速 |
线程 | Swift 结构化并发 |
C++ 字符 | swift字符串 |
AppKit/UIKit | SwiftUI |
OpenGL | SceneKit 和metal |
它还涉及重构和重写通过功能的分段演化而变得笨重的核心算法。
在过去的18 个月里,我一直在重写所有内容。这是我学到的。
我喜欢 Swift 的语法。C++ 所必需的大量重复样板代码在 Swift 中消失了,只留下了表示逻辑所需的代码,使含义更加清晰。Swift 在集合类中使用值类型使得对它们的推理更简单;语法糖使使用它们变得非常容易,并且它们还得到了一个实现的支持,该实现使用自动引用计数和写时复制来使它们几乎在所有用途中都具有高性能。(发现该语句的限制仍然是优化图形计算器性能的一个重要问题。)使用 Swift String 及其内置的 Unicode 支持取代了混乱的 C++ char、UTF-8 和 UTF-16 表示,改进了代码组织并使对代码的推理更容易。ARC,类型推断,可选项,闭包,
最后,该移植更易于维护、可读性和紧凑。当我移植单个功能部分时,Swift 源代码通常测量出相应 C++ 代码大小的 30%。(虽然代码行数不是一个信息量很大的指标,但它很容易衡量。)更少的代码意味着更少的调试,更少的阅读和理解,仅此一点就使移植更容易维护。使用 SwiftUI,视图控制器完全消失了:声明式编程优于命令式编程的一大胜利。总之,源代码从 152,000 行减少到 29,000 行,而功能或性能没有明显损失。
移植的最大挑战是实现可比的速度。数十年的迭代细化和每个版本的低级优化为性能设置了很高的标准。在性能关键代码中导航 Swift 的无数 Unsafe API 很困难,但很有效。剩下的最大挑战最小化 ARC 保留/释放导航表达式树的开销。依靠 ARC 消除了大量的代码复杂性。C++ 代码手动处理表达式内存管理,这非常脆弱但也非常快。Swift 版本更小,更容易编写正确的代码和推理,但有性能关键部分,我知道遍历树不会更改任何引用计数,但无法与编译器沟通 ARC 保留/释放开销是不必要的。Swift 语言、库和运行时具有出色的文档,甚至可以在紧要关头检查开源实现。相比之下,SwiftUI 框架是闭源的。当 SwiftUI 工作时,它是一种近乎神奇的乐趣,
我值得花时间移植到 Swift 吗?我很喜欢学习 Swift,并且对现在的代码状态更满意。用 Swift 写作是纯粹的快乐。自 80 年代以来,我一直打算最终开源我的代码。当我考虑使用 C++ 代码库时,我意识到这不会是一个有用的贡献,因为数十年来积累的技术债务使得 C++ 代码无法维护。我现在有信心将新代码制作成有用的独立 Swift 包,用于数学排版、编辑、数字和符号计算以及绘图。
Swift 兑现了实现安全、快速和富有表现力的代码的承诺。SwiftUI 兑现了其承诺,即以最少的代码在 Apple 平台上实现出色的用户体验。我要感谢所有为 Swift 做出贡献的人的辛勤工作。用 Swift 编程真的很有趣。
图形计算器可在macOS和iOS上使用。