Hikari Playground 仕様
本書は web の Playground (web/play.html) の利用者から見える面を定める。Playground はブラウザーの中で処理系そのものを走らせ、編集中のソースをその場で検査・整形・実行する。言語の意味論は language-spec.md、各モジュールの契約は std/index.md を参照。
面のうち、対応する仕様を既に持つものはそちらが正である — 図のペインは diagram.md「Playground からの表示」、対話端末での std:term の答えは std/term.md、ブラウザー REPL は repl.md。本書が定めるのは実行対象の振り分けと、他の仕様が持たないサーバーペインである。
ブラウザー向けのビルドと配線 (どの口をどう開けたか) は仕様ではなく ../internals/wasm-host.md が持つ。
実行の振り分け
Run はソースが import するモジュールで振り分ける。判定はエディターの内容と、例が同梱するファイルの両方を見る (パッケージ例では同梱モジュールが import することがあるため)。
| ソースが import するもの | 通る道 |
|---|---|
std:term |
対話端末 (xterm.js + Web Worker)。std/term.md |
std:http/server |
サーバーペイン (本書「サーバーペイン」) |
| それ以外 | VM がその場で走らせる。*_test.hika はテストとして走る |
判定は上から順に見る。std:term と std:http/server を両方 import するソースは対話端末で走り、サーバーペインには入らない。
時計は待った分だけ進む
ブラウザーの中の時計は待ちで進む。sleep や未解決の Future の待ちで待った分だけ prelude.md §9.3 の now! が進み、計算しただけでは進まない。
start := now! range(0, 2000000).fold(0) { acc, i | acc + i } # 計算だけ now! - start # ブラウザーでは 0(手元では実測の経過が出る)
sleep を跨ぐ測り方(sleep 100 の前後の差は 100)と、待ちの順序は手元と同じである。違うのは「計算に何ミリ秒かかったか」を測る用途で、そこはブラウザーでは測れない。配線の理由は ../internals/wasm-host.md が持つ。
サーバーペイン
std:http/server の serve (std/http/server.md) が待ち受けている間、利用者は要求を任意のタイミングで組んで送れる。送るのは人だけではない — 同じプログラムが std:http/client で自分の待ち受けへ投げた要求も同じペインに現れる (std/http/client.md)。
待ち受けは押すまで生きる
Run で待ち受けに入り、Stop まで同じインスタンスが生きる。起動時の出力は 1 度だけ出て、state は要求をまたいで積み上がる。shutdown が解決すればその時点で終わる。
Run を押し直したときは、今立っているものを閉じてから立て直す。編集しただけでは閉じない — 走っているサーバーは Run するまで古い綴りのまま答える。
ツールバー
ペインの上端にツールバーを 1 枚敷く (図のペインと同じ組み立て)。ツールバーは待ち受けの表示・method・path・送信の口を 1 行に持ち、ヘッダーと本文は閉じた欄として持つ (既定は閉じ)。
- path はクエリ込みで書ける。
pathとqueryへの分割は実装が行う - ヘッダーは 1 行 1 件で書く
- 待ち受けていない間は送信の口を閉じる — 押しても何も起きない口は置かない
- 待ち受けているかどうかは文字だけで示さない。立っているかが一目で分かることが要るためである
ログ
要求・ハンドラーの出力・応答を送った順に 1 本で並べる。走っているサーバーの記録は端末で読む形と同じ並びになり、ハンドラーが何を書いてからどう答えたかが 1 か所で読める。
- 要求ごとに、それを起こしたのが人 (ツールバー) かプログラム (
std:http/client) かを示す - 応答が落ちたこと (500) は、成功と見分けが付く形で示す
- Stop を押してもログは残る — 押した瞬間に読んでいた記録が消えない
- 待ち受けの開始と終了はログに現れる。終了は理由 (停止・再実行・
shutdown) と一緒に示す
serve を呼ばずにプログラムが終わったときは、待ち受けに入らなかったことを示して通常の出力ペインへ戻す。検査で落ちたときはサーバーペインを開かず、静的検査と同じ出力ペインへ診断を出す。
サーバーペインが持たないもの
以下は持たない。ブラウザーで再現しない挙動は serve と std:http/client の側の制約なので、それぞれ std/http/server.md と std/http/client.md が定める。ここに挙げるのは Playground 側の話である。
- 応答の描画 — 応答は綴りとしてログに出るだけで、HTML を描かない。したがってリンクを踏む・フォームを送るといった操作はペインに無い
- 要求の重なり — 送信は 1 件ずつで、人が同時に 2 本投げる口を持たない。ハンドラーの中で待つ間に別の要求が進むこと自体は
serveの並行モデルのまま働くが、それを人の操作から起こす手立ては無い - 複数ファイルの編集 — エディターは 1 枚で、同梱ファイルは例が持つものを読むだけである。サーバーとクライアントを別ファイルに分けて書く形は取れない (1 つのファイルに両方書く形は取れる)
- 待ち受けを跨いだ再利用 — 待ち受けが生きているのは、そのプログラムが
serveで止まっている間だけである。別に走らせたプログラムからその待ち受けへ届く道は無い