将 Scheme 带入 Web:Hoot 0.9.0 概述

随着 Hoot 0.9.0 的发布,函数式编程与 Web 技术的交汇正在不断演进。Hoot 作为 Guile Scheme 的专用 WebAssembly (Wasm) 编译器后端,有效地使开发者能够在浏览器中直接运行 Scheme。通过弥合高级 Lisp 方言与 Wasm 高效性之间的鸿沟,Hoot 为 Web 开发开启了新的可能性,从交互式应用到基于浏览器的游戏。

此最新版本专注于工具链的成熟化、通过更好的调试支持提升开发者体验,以及扩展运行时的灵活性以支持标准 JavaScript 驱动的浏览器之外的环境。

增强工具链与调试

Hoot 0.9.0 最显著的变化之一是其调试和元数据处理的现代化。编译器已从传统的函数名和源码元数据转向使用 DWARF custom section

关键变化包括:

  • 默认调试: 默认调试级别现已设置为 1,这会自动发出 DWARF 数据。对于生产环境,开发者可以使用 -g0 或新的 hoot strip 命令来移除这些数据并减小二进制文件大小。
  • 标准化异常: Hoot 已从传统异常转向标准 Wasm 异常(于 2025 年 7 月正式采用)。这确保了与不断演进的 Wasm 规范更好的对齐,并提高了在现代浏览器中的稳定性。
  • CLI 优化: 命令行界面已得到精简。guild compile-wasm 命令现已弃用,取而代之的是 hoot compile。此外,特性标志(使用 -f)已与调试选项(使用 -g)解耦,从而在程序行为和诊断输出之间提供了更清晰的区别。

运行时演进与非 JS 支持

虽然 Hoot 主要与浏览器相关联,但 0.9.0 版本致力于支持非 JavaScript 运行时,特别提到了 Wastrel

为了实现这一点,实施了若干架构变更:

  • 宿主提供类型 (Host-Provided Types): 引入宿主提供类型有助于更好地与 Wastrel 集成。
  • 基于 Scheme 的转换: 浮点数到字符串的转换现在直接在 Scheme 中实现,而不是依赖外部导入。虽然这略微增加了二进制文件大小,但它消除了对 JavaScript 运行时的关键依赖。
  • 单态化大整数 (Monomorphized Bignums): Bignum 导入已进行单态化处理,以减轻非 JS 运行时的负担。
  • 标准化入口点: Scheme 二进制文件现在导出一个 main 函数,该函数调用内部的 $load 函数,允许 Wastrel 在不需要 Scheme 反射接口的情况下启动 Hoot 程序。

语言与编译器改进

除了基础设施之外,Hoot 0.9.0 还对 Scheme 实现和编译器后端引入了若干改进:

  • Guile 兼容性: 后端已更新以支持 Guile 3.0.11 中引入的新原生字节向量谓词,并且 hash-set!(及相关函数)现在返回传递的值以符合标准 Guile 行为。
  • Typed Arrays:(hoot typed-arrays) 模块中新增了 uint8array->bytevector 过程,简化了 Wasm 与 JavaScript 之间的数据处理。
  • Record Types: Scheme 解释器现在支持用于具有多达 8 个字段的记录的 define-record-type,并计划在未来的版本中进一步扩展。
  • 优化: fsqrt 导入已被原生 f64.sqrt 指令取代,从而提高了性能。

实际应用:Lisp Game Jam

为了展示 Hoot 的实际效用,Spritely Institute 发布了一个 Hoot game jam template。该模板专为 Lisp Game Jam 设计,并为 HTML5 游戏开发提供了一个全面的起点,包括:

  • Web API 和 HTML5 canvas 的绑定。
  • 一个用于编译和部署到 itch.io 等平台的 Makefile。
  • 游戏手柄输入支持(由 Gonzalo Delgado 贡献)。

现有的项目如 CirkobanStrigoformShields TYVM 可作为概念验证示例,展示了将 Scheme 的灵活性与 WebAssembly 的可移植性相结合时可以实现的效果。

兼容性与安装

Hoot 0.9.0 保持了广泛的浏览器兼容性,支持 Safari 26+、Firefox 121+ 和 Chrome 119+。

用户可以通过 GNU Guix 使用 guix install guile guile-hoot 进行安装。它也正在进入 Debian 仓库,尽管发布时间表可能会有所不同。对于那些偏好手动设置的用户,可以通过 Hoot 主页上的发布压缩包进行获取。

Sources