出力先に重ねる層があるなら、状態を溜めずに済む
プレゼンツールには共通の要求がある。「このスライドのコード枠だけ、もう少し右に寄せて小さくしたい」— 一枚ごとの手作業の微調整だ。そしてその調整は、Markdownを直して再生成しても消えてはならない。
素朴に解くと、生成器は純粋関数でいられなくなる。k1LoW/deckはGoogle Slides上のスライドに調整を溜め、再生成のときにそれを避けて更新する。つまり出力先が状態を持つ。
peithoは純粋な生成器のままこれを実現している。調整はスライドキーを的にしたCSSの上書きとして、ソース側に置かれる。
[data-slide-key="arch-1"] .slot-code { grid-column: 2 / 3; width: 60%; }
再レンダリングすれば同じHTMLが出て、同じCSSがまた重なる。調整は「残る」のではなく「毎回やり直される」。 純粋関数のまま、調整が生き延びる。
差を作っているのは純粋性への意志ではない
ここが面白いところで、peithoが状態を持たずに済んでいるのは設計者がより厳格だったからではない。出力先の性質が違うからである。
HTML/CSSにはカスケードがある。後から書いた規則が先の規則に重なるという合成の仕組みが、出力媒体そのものに備わっている。Google Slidesにはそれが無い。だからdeckには対象に状態を溜める以外の選択肢が無かった。
一般化
出力先が「重ね合わせ」を持つなら、調整は差分の層としてソース側に置ける。持たないなら、調整は出力先に溜まる。純粋性は意志の問題ではなく、出力媒体が合成的かどうかで決まっている。
これはデプロイ計画がモノイドかモナドかで見通しが決まるが扱う話の、出力先の側から見た版である。あちらは成果物の構造(平らな列か、継続が残るか)が何を可能にするかを見ていた。こちらは成果物を受け取る先に結合則があるかを見ている。
IaCとの対応と、対応しない部分
IaCのstateは「現実がどうなっているか」の帳簿で、import / removed / moved は現実を動かさずに帳簿だけを書き換えるの言う通り現実を動かさずに書き換えられる。peithoのCSS上書きはこれとは違う — 現実(ブラウザの描画)は毎回ゼロから作り直される。
対応しているのはなぜstateが要るのかという問いの方である。IaCがstateを持つのは、クラウドという出力先が「宣言を重ねる」ことを許さず、命令的なAPIしか受け付けないからだ。もしクラウドがカスケードのように「望ましい状態の層を重ねると合成される」性質を持っていれば、worldの取得の問題ごと形が変わっていたはずである。
stateは本質的な必要物ではなく、出力先が非合成的であることへの補償である。