**Scheme を WebAssembly にコンパイル**

2026/01/18 8:29

**Scheme を WebAssembly にコンパイル**

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:


Summary

Pythonで実装されたオープンソースScheme実装「Bob」は、15周年を記念してネイティブWASMバイナリを生成するWebAssembly(WASM)コンパイラを追加しました。新しい

WasmCompiler
は解析済みのScheme式を直接WASMテキストに変換し、その後 wasm‑tools スイートでコンパイルされ、Node.js経由で実行されます。

コンパイラの核心は、Schemeプリミティブを実装する約1,000行のWASMコードから成ります:

  • オブジェクト表現 – SchemeオブジェクトはWASM GC型にマッピングされます:
    • $PAIR
      構造体は
      car
      cdr
      (ref null eq)
      参照として保持します。
    • $BOOL
      構造体は単一の
      i32
      (0 = false、非ゼロ = true)を保持します。
    • $SYMBOL
      構造体は線形メモリ内でオフセットと長さを表す2つの
      i32
      を保存します。
  • 数値 – 整数値は
    i31
    型を使用してボックス化されていない整数を直接参照します。
  • シンボル – シンボルは線形メモリに固定オフセット(例:
    (data (i32.const 2048) "foo")
    )で発行され、アドレス/長さペアで参照されます。
  • 組み込み関数
    write
    関数はWASMテキスト内で直接実装され、ホスト関数として
    write_char
    write_i32
    の2つだけをインポートします。

Bobはすでにインタープリタ、コンパイラ、VM、およびカスタムマーク・アンド・スウィープGCを備えたC++ VMを提供しています。追加されたコンパイラは今後さらに進化する予定ですが、現在のwasmtime用Pythonバインディングは2023年10月に仕様に組み込まれたWASM GC提案をまだサポートしていないため、SchemeをWebAssembly上で完全にガベージコレクション実行することが制限されています。

それでもユーザーは今やSchemeを直接WebAssemblyとして実行できるようになり、クロスプラットフォームのデプロイメントとJavaScript/Node.js環境とのより緊密な統合の可能性が開かれます。

本文

Bob – Python と C++ で実装された Scheme 実装スイート

私の最古のオープンソースプロジェクトの一つ、Bob は数か月前に 15 歳を迎えました。

Bob は Python で書かれた Scheme 実装群です。インタプリタ・コンパイラ・仮想マシン(VM)が含まれています。
その頃は CPython の内部実装を改造していたので、CPython スタイルのバイトコード VM がどのように動作するかを理解したかったため、R5RS Scheme 用にゼロからこうした VM を構築する実験として Bob を始めました。

その後、Python のランタイムサポート(組み込み GC など)が無い低レベル言語でこれらのマシンがどのように作られるかを学ぶため、C++ VM をスイートに追加しました。C++ VM は独自の mark‑and‑sweep GC を実装しています。

数年間ほとんどメンテナンスだけ(主に見た目の変更、GitHub への移行、Python 3 用アップデート)をしていた後、休暇直前に Bob を再訪する必要性を感じました。そこで新しいコンパイラを追加しました:Scheme → WebAssembly


目的

  1. 高レベル言語である Scheme を WebAssembly に低下させる実験
    「Let's Build a Compiler」プロジェクトは通常、C レベルの toy 言語を対象にしています。Scheme は組み込みデータ構造・レキシカルクロージャ・GC が備わっているため、より難易度が高いです。

  2. WASM GC 拡張機能 [1] を実務的に体験

    wasm-wat-samples
    リポジトリのサンプルはあったものの、実際のプロジェクトで適用したかったためです。


概要

Bob の新しい構成要素は右側の垂直パス:

WasmCompiler
クラスが解析済み Scheme 式を WebAssembly テキストにまで低下させ、そこからバイナリへコンパイルして標準 WASM ツールで実行できるようにします [2]。

主な特徴

  • WASM GC を使って Scheme オブジェクトを表現
    すべての値を参照(

    ref
    )でボックス化・ラップすれば、基盤となる WASM ランタイムがメモリ管理を行います。

  • Scheme オブジェクトの主要な表現

;; PAIR は cons cell の car と cdr を保持する。
(type $PAIR (struct (field (mut (ref null eq))) (field (mut (ref null eq)))))

;; BOOL は Scheme 真偽値。0 → false、非 0 → true。
(type $BOOL (struct (field i32)))

;; SYMBOL は Scheme シンボル。線形メモリ上のオフセットと長さを保持する。
(type $SYMBOL (struct (field i32) (field i32)))

$PAIR
が特に興味深い点は、フィールドが任意のオブジェクト(
ref null eq
)を含められることです。
ref.test
命令で参照の実行時型をクエリできます。

  • 数値

    i31
    型で表現されます。これは整数を参照内にボックス化せずに格納し、1 ビット差異で本物の参照と区別します。専用の数値型は不要です。

  • シンボル は文字列として手動で保持します。WASM には組み込み文字列サポートがないためです。コンパイラは線形メモリにシンボル文字列を書き込み、

    $SYMBOL
    にオフセットと長さを保存します。これにより同一シンボルのインターリングも効率的に行えます。

例:

;; シンボル用線形メモリ
(data (i32.const 2048) "foo")
(data (i32.const 2051) "bar")

;; シンボル値を構築
(struct.new $SYMBOL (i32.const 2051) (i32.const 3))

write
の実装

組み込みの

write
関数は、リストやシンボルなど任意の Scheme 値の再帰的表現を出力する必要があります。

  • ホストへ委譲すると、ホストは WASM GC 参照にアクセスできないため問題があります。
  • 別言語(例:C)から低下させても WASM GC オブジェクトの表現が難しいです。

したがって

write
を WebAssembly テキスト内で直接実装し、AI のヘルプを得てボイラープレートを書きました。インポートされるホスト関数は 2 つだけです:

(import "env" "write_char" (func $write_char (param i32)))
(import "env" "write_i32"  (func $write_i32  (param i32)))

例えば、標準 Scheme 表記(

#t
/
#f
)で真偽値を出力するには:

(func $emit_bool (param $b (ref $BOOL))
  (call $emit (i32.const 35)) ;; '#'
  (if (i32.eqz (struct.get $BOOL 0 (local.get $b)))
      (then (call $emit (i32.const 102))) ;; 'f'
      (else (call $emit (i32.const 116)))) ;; 't'
)

ほとんどの出力には最低レベルの

write_char
を使用し、整数のエミッションは
write_i32
に委ねます。


結論

このプロジェクトは非常に楽しく、実際の WebAssembly コード生成について多くを学びました。

WasmCompiler
のソースは十分にドキュメント化されています。総計 1 000 行を超えるコード([4])で、その半分以上が最小限の Scheme 実装に必要な組み込み型と関数を実装する WASM テキストスニペットです。


参考文献

[1] The GC proposal – 2023 年 10 月に公式に WASM スペックに追加。
[2] Bob ではテキストからバイナリへの変換に

bytecodealliance/wasm-tools
を使用し、Node.js がバイナリを実行します(将来的には Python バインディングが Wasmtime の WASM GC をサポートするかもしれません)。
[3] 2048 はシンボル格納のためにコンパイラが選んだ任意オフセットです。WASM の複数メモリ機能を使えば別線形メモリを用いることも可能です。
[4] 1 000 行は
WasmCompiler
クラスのみの計で、他のコンポーネント(パーサ・レキサ・共有 Scheme 表現)は含まれていません。

ぜひ

WasmCompiler
のソースコードを覗いてみてください。

同じ日のほかのニュース

一覧に戻る →

2026/01/23 0:20

**GPTZero、NeurIPS 2025受理論文で新たに100件の幻覚現象を発見**

2026/01/23 2:41

**CSS の光学的錯覚**

## Japanese Translation: (すべての主要なポイントを統合したもの) > 記事は、マウスホバーに応じて反応するインタラクティブな CSS ベースの錯視デモの CodePen ギャラリーを提示しています。 > 各デモは、Poggendorff の歪んだ線(傾いた 2 つのグラデーションと `::before`/`::after` を使用)、誘導グラデーション効果、Cornsweet & White の色コントラストトリック(黒白格子に `mix-blend-mode` を適用)、リングおよびチェッカーボードパターン、重なり合う線の色球体、曲率盲点、Café Wall イルлю(3 本のグラデーションで平行線を斜めにする)、ペノース三角形やエビングハウス円、カニッツァ四角形など、古典的な視覚現象を示しています。 > ギャラリーには、エビングハウス錯視のアニメーション版、回転する「タワー」、色のファン、逆スピーク、モーションバインディング、メンツラインズ、ウォッリングカラーなども含まれ、ドット線の動きやコントラスト非同期、息を吸う四角形、トロックラー消失といった静的に動きを示唆するパターンも掲載されています。 > すべての効果は CSS グラデーション、疑似要素、`mix-blend-mode`、およびキーフレームアニメーションで実現され、微妙な背景やホバー変更がどれほど印象的な視覚トリックを生み出せるかを示しています。 > コレクションは Patrick Pester の「35 optical…」リストと Michael Bach の「154 Visual Phenomena & Optical Illusions」に触発されています。 > Medium と DEV に公開されており、著者は将来の追加や改良の可能性について読者にコメントを残すよう呼びかけています。 *この改訂された要約は、すべての主要なポイントを完全に反映し、推測を加えず、明確で簡潔に保っています。*

2026/01/23 4:03

**アクティブ・シッティングは脳健康に有益:研究レビュー**

## 日本語訳: **要約** 最近の研究では、座り方が脳の健康に影響することが示されています。85件の研究を系統的にレビューした結果、**精神的に活動的な座位**(読書や戦略ゲームへの参加、会話など)は実行機能と記憶力を向上させる一方で、**受動的な座位**(例:テレビ視聴)は認知機能の低下および認知症リスクの増加に関連していることがわかりました。クイーンズランド大学のポール・ガーディナーを筆頭とする著者らは、正式な脳トレーニングプログラムではなく、日常的な座位行動を検討しました。その結果、公衆衛生指針は受動的座位と活動的座位を区別し、人々が座ったままの時間に精神刺激的なタスクを取り入れ、短い休憩で身体を動かすよう奨励すべきだと示唆しています。この変化は個人の選択(受動メディアより本やインタラクティブゲームを好む)に影響し、保健機関からの新しいガイドラインを形成し、家具・エンターテイメントデバイス・職場環境の設計者が活動的座位習慣を促進するよう促す可能性があります。また、認知的幸福感に対する微細な推奨事項についてさらに研究が進むことも期待されます。