互联网计算机的本地语言 Motoko 两岁了
Motoko 两周年快乐!
两年前,我们宣布推出 Motoko,这是一种为互联网计算机设计的基于 actor 的编程语言。在此期间发生了很多事情 —— 最值得注意的是,互联网计算机终于经历了创世并推出。
从那时起,许多项目都采用 Motoko 进行开发并在互联网计算机上运行,在 GitHub 上有大约 400 个存储库。项目和存储库在技术上变得越来越复杂,dapps 和开放的互联网服务采用不同的容器,其中核心“业务逻辑”是用 Motoko 编写的,但相关的数据存储或令牌可能会用 Rust 实现。通过这种方式,我们看到 WebAssembly 支持的动态系统越来越多。
在过去的一年里,Motoko 团队也没有闲着,我们一直致力于改进 Motoko,包括语言及其实现,并使其更易于使用和访问。
开源
Motoko 团队最大的里程碑是该语言及其库终于开源,我们已经为这个目标努力了很长时间,但在它最终发生之前,必须解决各种技术和组织障碍(例如测试基础设施)。Motoko 及其基础库现在在 GitHub 上公开,包括所有来源以及完整的问题和提交历史,对外部贡献者开放。
也许更明显的是,Motoko Playground 启动了,通过允许用户通过一个简单的网页部署和测试容器,它极大地降低了使用 Motoko 语言和互联网计算机的门槛。我们 Motoko 团队发现自己一直在使用 Playground 在功能齐全的 Motoko+IC 环境中尝试简单的事情。
Vessel 是 Motoko 的包管理器,也已成为 Motoko 生态系统中更为核心的部分,它允许开发人员轻松地将第三方库拉入他们的项目或将他们自己的库提供给其他项目。
Motoko 文档也有许多改进和补充,当然还有更多工作要做。该文档现在也是开源的,我们欢迎社区以改进建议或实际材料的形式做出贡献。
内存
目前对我们来说最重要的项目是让 Motoko 对内存的使用更具可扩展性,如您所知,Motoko 是一种托管语言,这意味着程序员无需担心内存管理的细节和容易出错的细节。
这是通过垃圾收集器实现的,这是 Motoko 编译器添加的一段代码,用于发现何时不再需要数据并且可以回收它使用的空间。垃圾收集器在所有高级编程语言中都有使用,它们的最新技术已经达到了超越大多数手动管理内存尝试的复杂程度。
话虽如此,Motoko 一开始是一个非常天真的收集器,因为这是让我们起步的最快方式。这是一个简单的半空间收集器,它不断地将活动数据从活动堆的一半复制到另一半。但是我们的早期采用者正在以比我们预期的更快的速度将 IC 带到其存储容量的极限,因此很明显我们需要快速改进。
在将整个运行系统从 C 重写为 Rust 之后,我们现在提供了一个使用更少空间的压缩收集器。我们还大幅改进了收集的调度,以便它们仅在可能积累了足够垃圾时发生。
现在,我们正在朝着基于页面的堆发展,这将允许将收集器的工作本地化到单个 IC 内存页面,从而通过一次只弄脏几个页面来减少内存费用。这是下一个重大改进的先决步骤:一个现代的分代和最终增量收集器,它最大限度地减少垃圾收集并将其分解为小的、连续的工作包,这些工作包可以随着时间的推移均匀处理,避免不可预测的循环使用高峰。
另一个重要的话题是稳定的内存,这是一个独立的内存区域,IC 允许在容器升级中幸存下来。在 Motoko 实现中,我们使用它在升级之前自动备份容器的稳定变量的内容。不幸的是,这可能是昂贵的。
理想情况下,人们希望直接在该内存区域中存储稳定的数据,但将垃圾收集扩展到这一点将需要直接访问该内存才可行,而 WebAssembly 和 IC 尚不支持。作为权宜之计,我们很快将提供手动访问稳定内存的接口,希望社区能够构建库抽象,例如键/值存储甚至驻留在稳定内存中的数据库。
安全的容器升级
我们的另一个重要课题是提高容器升级的安全性和可靠性,dfx 始终计划能够检查新容器版本的接口是否向后兼容旧版本,从某种意义上说,所有依赖它的现有客户端(尚未)意识到升级将继续发挥作用。
我们专门设计了 Candid,以可检查的方式定义什么是安全升级。这是根据 Candid 接口上的子类型规则来表达的,Joachim 最近在博客系列中解释了这些。我们实际上能够正式证明,作为机器验证的健全性声明的一种形式,这些规则正确地防止了客户端被破坏。但是,虽然这是从一开始就计划好的,但我们现在才开始将基础设施构建到 IC、dfx 和 Motoko 编译器中,以实际执行这些检查。
稳定变量会出现类似但独立的问题,虽然这些不是容器的公共接口的一部分,但它们是容器的两个版本之间的一种私有接口,通常需要以类似的方式进行检查。具体来说,新的容器应该仍然能够读取现有稳定变量的内容,这需要在升级过程中限制对其类型的更改,否则容器可能会意外丢失数据,该检查及其基础设施目前也由团队实施。
语言特点
当然,我们也改进了 Motoko 语言本身。我们增加了生活质量功能,并整合了设计中一些不太合适的方面。
例如,do? 区块使得使用选项类型 ?T 更加方便,您不再需要打开每个选项来访问其值。相反,插入单个 bang! 就足够了,前提是整个计算都包含在一个 do? 区块中,以在某个外部级别封装错误情况。将来,我们计划将此功能推广到其他类型,例如 Result。
Motoko 的结构类型系统的另一个痛点是,没有允许通过扩展先前定义的类型以增量方式定义对象或变体类型的“继承” —— 相反,所有字段都必须重复。现在,由于引入了新的类型级运算符 and 和 or,这已经变得不必要了,它们表达了使用附加信息细化给定类型的方法,甚至可以组合两种类型。
在整合方面,比如,我们细化了对象和区块语法不太明确的,并且我们去掉了笨拙的 WordN 类型,青睐在另外的运营商的需要进行繁琐的转换 NatN 和 IntN 类型的家庭。我们还对类型检查进行了各种改进,尤其是在使用重载运算符或文字时减少了对虚假类型注释的需求。最后但并非最不重要的是,我们试图使编译可重现,即避免对环境的依赖,例如断言错误消息中出现的源文件路径。
我们一直在考虑许多其他不错的语言功能,希望将来能实现。但我们目前正致力于整合语言并使其更具可扩展性和安全性,包括一些性能优化,例如迭代数组。
库
最后但并非最不重要的一点是,库也很重要。随着时间的推移,Motoko 基础库中增加了各种较小的内容,但很明显,总会有更多内容。作为开源的一个好处,我们希望社区做出贡献,使 Motoko 库更丰富,或者第三方提供他们自己的额外库,使它们可以通过容器访问。
我们现在的主要目标是通过当前无法访问的系统库来公开 IC 的一些功能,例如,传输 Cycles、直接访问稳定内存(具有 64 位地址范围)、支持方法访问检查,也许还有心跳。其中一些已经以实验形式存在,但在我们正式向世界发布之前还需要进行更多调整。
最后,我们意识到目前很难测试和调试 Motoko 程序,尤其是当它们应该与其他容器交互时。不幸的是,在很大程度上,由于 IC 本身的性质,这是一个不重要的问题。例如,它显然不允许设置断点或单步执行在网络上实时运行的代码,因为这与其底层区块链模型不兼容,后者不支持计算的随机中断。
所以一般的问题在 Motoko 这边是无法真正解决的,有一些想法可以提供用于观察直播节目的状态或行为的机制,但这需要时间来设计和在系统中实现。在那之前,我们希望通过至少向 Motoko 添加更简单的日志记录和离线调试工具来尽可能地缓解这种情况。
社区
当然,如果没有社区,一种语言就毫无价值。我们对语言的积极反应以及建设性的批评和改进建议感到非常兴奋。如果有些事情需要时间,请耐心等待。
我们想借此机会邀请社区为 Motoko 及其库、文档和生态系统做出贡献,无论您是参与论坛、提交问题或功能请求、创建 PR,还是通过容器发布您自己的库 —— 一切都是受欢迎的,让与 Motoko 合作更高效、更方便、更有趣!
开始在 smartcontracts.org 上构建并加入我们的开发者社区 forum.dfinity.org。
来源:DFINITY
翻译:Catherine
- 往 期 推 荐 -
长按关注 DFINITY 微信公众号
随时答疑解惑
*添加小助手微信 comiocn 进交流社群