ドメインモデリングにおける抽象の役割、tagless-finalによるDSL構築、そして型安全な最適化
https://fortee.jp/2025fp-matsuri/proposal/f3a8809b-d498-4ac2-bf42-5c32ce1595ea
https://speakerdeck.com/knih/reification-of-abstraction
ドメインモデル は使う側に意味の判断を委ねると、意味を喪失する
ドメインモデルの崩壊
意味の曖昧さは 偶有的複雑性 の起点となる
DSL をドメインの意味を直接表現することが可能
これにより、誤った意味をそもそも記述できないようにすることが可能
DSL = 意味を埋め込める、型安全なインタフェースと捉えられる
DSL を用いてドメインの言葉で直接問題を記述すると、ビジネスの本質をそのままコードに落とし込むことで、偶有的複雑性を排除できる
モデルを言語として定式化することで、どの操作が許され、どの解釈が正当かを型 + 構文レベルで制約できる
人月の神話 によると 複雑性 とは大きく 2 つに大別できる
本質的複雑性
偶有的複雑性
それぞれの性質に合わせた向き合い方が必要
https://gyazo.com/63985d717e8ea5b8b82cf3efc3e54d04
抽象の本質
https://gyazo.com/e9bb9f46f77ab9ea39edc8c368bd7a0e
ドメインモデルに適用すると、ドメインの意図を崩さず に本質を抽出し、その 意図を実装可能な形で表現 すること
つまり、課題の解像度を高め、予測可能性 を高めること
複雑で曖昧な 現実(問題空間)から「本質的で再現可能なパターン」を抽出し、解決空間 で 安定性 や 再現性 を高める
抽象 = 安定
抽象の役割: 問題空間 と 解決空間 の橋渡しをする
安定依存の原則 と 安定度・抽象度等価の原則
より安定してるものに依存させる
e.g. Clean Architecture
抽象の特性
本質を抽出する(意味のコアを形成する)
蒸留: 意味のコア以外のノイズを除去する
ドメイン知識 から本質概念を抽出し、DSL の語彙として定義する
特に重要
ノイズ = 抽象のコアとなる 関心事 に対応付けられないもの
https://gyazo.com/d1db39f3f6bcca47b5be7a30571edca9
最小化: 必要なものだけを公開する(カプセル化)
DSL に含める演算や型、操作を厳選し、誤用を減らす
表現力: 意図が伝わる
構造に作用する
合成可能性 DSL に対する操作が安全に合成可能であること
e.g. 式のネスト、関数合成
直交性: 他の構成要素と独立して機能し、干渉し合わない
拡張可能性
変更や検証のしやすさ
変更容易性
テスト容易性
tagless-final
型安全な埋め込み言語を構築する手法
DSL の型付けがホストとなる言語のそれに帰着する
HOAS が使える
コンポーネントの合成 が可能
パーサ が不要
対象言語とメタ(ホスト)言語
対象言語: Int、メタ言語: Repr[Int]
対象言語 = 表現したい言語
これらを分離することが大事
意味の曖昧さは偶有的複雑性の起点となる
言語を構成するもの: 構文、型付け規則、意味論
インタフェース(Symantics、構文 + 型付け規則)と複数の インタプリタ から構成
warning.icon メタ言語から対照言語の世界への流入経路は慎重に設計する
多層の値を受け取ると、意図しない値が世界に紛れ込む
tagless-final のメリット
扱いたいビジネスドメインを表現できるか早期に検証可能
偶有性複雑性を排除しながらコーディングが可能
Layered final
単なるデータではなく、意味を持ったドメインの計算対照をクエリしたい
そのため、独自のクエリ言語(DSL)を実装する
Nested Relational Caluculus(NRC)ベース
特に参照系が多い場合、クエリ自体がドメイン資産になる
が、SQL だとインフラ層に押し込められて再利用性が低い...
とはいえ、クエリにはパフォーマンス問題はつきもの
クエリ DSL を最適化するのが、Layered Final
多層のインタプリタを与え、最適化を施せるようにしたアプローチ
Ad-hoc Rewrite だと拡張や保守が困難であるため、管理しやすいようにパイプライン化
代数的正規化を行う
Layer 同士を繋ぐには、Embedding-Projection Pair 構造を構築することでパイプライン化できる
自然変換
まるで ミルフィーユ
Free モナド に近しいもの
層を追加しても削除しても、DSL 自体やユーザプログラムに影響はない
最適化や変換、トレーシングのためのログや Provenance を後付けしたい時に便利
ユーザプログラムや DSL 自体を早期に検証できる旨みは健在
ソフトウェアプロダクトライン(SPL)
似て非なるユースケース差分をどうするか
汎用エンジンに寄せる: 重厚長大化
個別・個社開発寄せる: 保守難易度高
これらの中間として DSL が使えるのでは?
AI + SPL + DSL で型安全で開発の出力を最大化できるかも?
#関数型まつり_2025