世界を動かす技術を、日本語で。

Hoot: WebAssemblyにおけるスキーム

概要

  • Hoot はSchemeコードを Wasm GC対応ブラウザ 上で実行可能にするプロジェクト
  • Scheme to Wasmコンパイラ充実したWasmツールチェーン を搭載
  • Guile 上に構築され、追加依存なし
  • Guile REPL内で Wasmバイナリのテスト も可能
  • 最新リリースは v0.7.0

Hootプロジェクト概要

  • Hoot は、 Spritelyプロジェクト の一環として開発
  • SchemeコードWasm GC対応のWebブラウザ で動作させるための基盤
  • Scheme to Wasmコンパイラ の搭載
  • Wasmツールチェーン が全て含まれる自己完結型設計
  • Guile 上で動作し、追加依存パッケージ不要
  • Wasmインタプリタ も内蔵し、 Guile REPL からHootバイナリのテストが可能

Hootの主な特徴

  • 自己完結型ツールチェーン によるシンプルな運用
  • ブラウザ上でSchemeコード を直接実行可能
  • Wasmバイナリのテスト をローカル環境で即時実行
  • 開発者向けドキュメント署名付きリリース の提供

入手方法とリソース

  • 最新版:v0.7.0
    • 署名ファイルドキュメントリリースアナウンス あり
  • 開発版git リポジトリで公開
  • 公式サイト から「Try Hoot!」「Get Hoot!」で体験・ダウンロード可能

関連記事・動画

  • Hoot Scheme in the browser: A Hoot of a tale
    • ブラウザ上でのインタラクティブWebページ構築事例
  • Lisp Game Jam - "Wireworld"
    • Hootの低レベルWasmツール活用例
  • Andy Wingo's blog
    • 開発者による技術解説
  • System Craftersによる開発者インタビュー
    • Hoot開発の裏側紹介

まとめ

  • HootSchemeとWasm の橋渡しを担う最新ツールチェーン
  • Web開発者Lisp愛好家 にとって革新的なプロジェクト
  • 今すぐ体験・導入 で新世代の開発環境を実感

Hackerたちの意見

すごいプロジェクトだね!でも、Guileじゃなくて他の何かを使ってほしかったなぁ。欲張ってはいけないけど。

Guileじゃなくて、他のSchemeの実装ってこと?Scheme間での移植はそんなに難しくないことが多いよ。特に、標準のR6RSやR7RSのライブラリ構文を使えばね。

Guileにはたくさんのライブラリがあるし、Guixの言語でもあるから、みんなが自分のものをGuix経由でパッケージ化する可能性が高いよね。Guix自体がエコシステムを豊かにしてるし、GuileプロジェクトはGuixを使って再現性を持たせることができる。ただ、いくつかの問題は残ってる。良いデバッガー、良いマクロ展開器(Emacsのgeiserはなんとか展開できるけど)、R6RSのライブラリ構文や標準ライブラリのバインディングの問題を解決することが思い浮かぶかな。Racketのマルチコア機能は長い間、ほとんどが重かった(場所を使ったり、まるで新しいRacket VMを立ち上げるみたいな)。ただ、futureの実装はあったけど、あれはいつも役に立つわけじゃなかった。最近Racketの状況は改善されたと思うけど、Guileのファイバーやfuture(Racketのfutureとは違う)と同じくらい良いかはわからないな。

すごくクール!これってCloudflare Workersでも使えるのかな?

これめっちゃ好き!未来について考えさせられたし、いろいろ調べちゃった。エージェントが主流のコードライターになると、「労働者階級」のプログラミング言語の最優先課題は、エラーを減らして明確さを向上させることになると思う。そうなると、言語はもっと明示的になって、人間が書くのは楽しくなくなるかもしれないけど、意図がはっきりしていて、壊さずに簡単に修正できるコードを生み出すのには良いと思う。生のRustはライフタイムや面倒な部分があって、個人的にはトップに来ると思う。まだ考えてる大きな疑問は、Hootのような言語はプロの世界で通用するのか?それとも、手作業でコードを書くのが好きな趣味の人たちに relegated されるのか。家庭菜園の趣味と現代農業の違いみたいなもんだね…。

AIファーストのプログラミング言語がどんなものになるかずっと考えてたんだけど、最も近いのはScheme/Lispみたいな感じかな。長い目で見れば、もっと人気が出るかもしれないね。

これがJavaScriptの本来の姿だったはずなのに、Netscapeがあの人にC/Javaっぽい構文を使わせることを強制したんだよね。

わーい!

最近のGuileの発展には驚かされるね。残念ながら、元Racketersが移ってきているみたい。コミュニティの分裂は悲しいな(特にGuileはRacketのパフォーマンスに大きく遅れをとっているし、Gaucheのような素敵なライブラリもないから)。

Guileが注目されてるのは嬉しいけど、Racketを軽視するのは良くないと思う。いくつかの考えを... * 最近のGuileのWASMに関する取り組みは期待できるね。(Racket関連のコンパイラでのJens Axel Soegaardの最近のWASMに関する仕事も注目だよ。) * RacketがChezの上に再ホスティングするのは良いアイデアだと思うし、Racketの内部は今やGuileより扱いやすいんじゃないかな。 * Racketは素晴らしい仕事をたくさんしてきたし、就職のキーワードを気にせずにツールを選べる人にはいいプラットフォームだと思う。広く受け入れられるチャンスがあったときにいくつかのミスを犯したし、業界の著名な貢献者が何人か去ってしまった。 * Racketは今でも最高のメタプログラミング機能を持っていると思う。ただ、syntax-parse#langよりも、Guileや他のSchemeから本当に欲しいのはRacketのモジュールシステムのサポートだね。(Racketのサブモジュールをインラインで定義できるのが好きなんだ。埋め込みユニットテストや埋め込みAPIドキュメントのためにね。) * 現在、Schemeはテックブロやプログラマーの面接を受けなくていい人たちのためのものになっている。プロフェッショナリズムの面でこの分野はしばらく悪い状態だったし、経済の問題(そしておなじみのVC成長投資詐欺のポストZIRPの混乱)や「AI」ロボ盗作への押し付け(新しい投資詐欺も伴って)で、ICにとってさらに悪化しているね。

特にGuileはRacketのパフォーマンスに大きく遅れをとっている へぇ、俺の経験とは逆だな。これに反するベンチマークがたくさんあるのを見たから、理由を調べる努力をしないといけないかも。もしかしたら俺が単に間違ってるだけかもしれないし... でも、予想するに、GuileはRacketのスタートアップ時間のペナルティがないし、俺がやることのほとんどはIOに依存しているから、GuileのIOの方がRacketより良いと思う。

Racketに分裂があったなんて知らなかった。これはCSとBCバックエンドのこと?それはもう過去のことだと思ってたけど。

Racketはあまり追ってないけど、数年前にコミュニティ内のかなり重要な貢献者が、別のさらに重要な(おそらく基盤的な)貢献者に関するMissing Stair問題についてブログを書いていたのを覚えてる。俺は完全に外部の人間で、そのブログをもう見つけられないし、言語にも全然投資してないから、当時のやり取りについての結論を出すのはためらうけど、ああいう出来事の後にコミュニティが分裂するのは避けられないと思うな。

Guileは現在JITを持つバイトコードVMだけど、全体的にはChez/Racketには負けてるかな。でも、正直言ってかなり速いよ。スムーズに60fpsで動くゲームを作れるし、GCの停止もあまりない。成長の余地はたくさんあるけど、Guileは決して遅くはないよ。Gaucheは使ったことないけど、最近のGuileにはいいライブラリがたくさんあるね。

こういうのを見るのは嬉しいな。WASMへのコンパイルの盛り上がりは少し前に終わったように思ったけど。もっとWASM言語が増えて、JavaScriptを避け続けられるといいな、ハハ!

repl.wasmは1.6 MiBか。ちょっと多い気がするな。todoの例はどれくらいの大きさになるんだろう?

これは一番小さいREPLバイナリではないけど、見た中では一番大きいわけでもないよ。自分の経験から言うと、平均よりちょっと小さいか、中間くらいのサイズかな。ウェブサーバーの設定をgzip圧縮してないから、これを圧縮すべきだね。gzippedのrepl.wasmは339Kだよ。このバイナリはwasm-optも通してないしね。Hootは主に事前コンパイラで、インタプリタじゃないから、このREPLデモには本番用バイナリにはないマクロ展開器やランタイムモジュールシステム、インタプリタが含まれてる。余分なコードがかなりあるよ。ちなみに、別のリポジトリにtodoリストの例[0]があるから、そっちも見てみて。自分のマシンでは、todo.wasmは566Kの未圧縮、143Kのgzippedだよ。これにはSchemeで実装された仮想DOMの差分アルゴリズムも含まれてる。とはいえ、バイナリサイズを最適化する余地はかなりあるよ。例えば、関数内でローカル変数を生成しすぎてるのが分かってるから、追加のコンパイルパスで最適化できる部分が多いんだ。これがバイナリサイズに大きな影響を与えると思う。あと、実装時にWasmに欠けていた機能のせいで、バイナリサイズが増えてる部分もあるよ。継続のためのネイティブスタック切り替えがないのがその一例。スタック切り替えの提案を採用すれば、いくつかのバイトを削減できるはず。[0] https://codeberg.org/spritely/hoot-ffi-demo/ [1] https://codeberg.org/spritely/hoot/issues/193

GuileがもっとWindowsサポートがあればいいのに。