Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Dhallによるリッチな設定ファイル体験
Search
syocy
June 29, 2018
Programming
0
6.2k
Dhallによるリッチな設定ファイル体験
LT in Japanese about dhall-lang
syocy
June 29, 2018
Tweet
Share
More Decks by syocy
See All by syocy
並列並行言語Haskell
syocy
4
3.7k
Dhall: Haskellの新たなキラーアプリ
syocy
4
4.2k
Other Decks in Programming
See All in Programming
Youtube Lofier - Chrome拡張開発
ninikoko
0
2.5k
SwiftUI API Design Lessons
niw
1
300
Building Scalable Mobile Projects: Fast Builds, High Reusability and Clear Ownership
cyrilmottier
2
310
小田原でみんなで一句詠みたいな #phpcon_odawara
stefafafan
0
350
REALITY コマンド作成チュートリアル
nishiuriraku
0
110
実践Webフロントパフォーマンスチューニング
cp20
35
7.9k
複雑なフォームの jotai 設計 / Designing jotai(state) for Complex Forms #layerx_frontend
izumin5210
4
1.2k
Lambda(Python)の リファクタリングが好きなんです
komakichi
3
220
SwiftDataのカスタムデータストアを試してみた
1mash0
0
100
Unlock the Potential of Swift Code Generation
rockname
0
270
RubyKaigi Dev Meeting 2025
tenderlove
1
400
七輪ライブラリー: Claude AI で作る Next.js アプリ
suneo3476
1
120
Featured
See All Featured
Optimising Largest Contentful Paint
csswizardry
37
3.2k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
47
2.7k
Being A Developer After 40
akosma
91
590k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
227
22k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
47
5.3k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
248
1.3M
ReactJS: Keep Simple. Everything can be a component!
pedronauck
667
120k
RailsConf 2023
tenderlove
30
1.1k
Side Projects
sachag
453
42k
Designing for humans not robots
tammielis
253
25k
Reflections from 52 weeks, 52 projects
jeffersonlam
349
20k
Become a Pro
speakerdeck
PRO
27
5.3k
Transcript
Dhallによるリッチな設定ファイル体験 @syocy 2018-06-29
設定ファイル書いてますか? 最初は小さく単純な JSON/YAML から始まるが…… ソフトウェアの成長に伴って役割が増えていく 気づくと数百行の JSON ができていたり 後段の機能に渡すために JSON
の文字列として JSON が入り込む 2 / 18
マクロの誘惑 設定ファイルにさらなる表現力を持たせたくなって くる しかし既存の設定ファイルを大きく変えたくない 独自マクロだ! → JSON 文法が破壊され構文ハイライト等が効かなく なる →実行時でないとどういう設定になるか分からなくなる
→表現力を上げすぎると無限ループのおそれもある 3 / 18
Dhall
Dhall? You can think of Dhall as: JSON + functions
+ types + imports – GitHub - dhall-lang/dhall-lang Dhall とは データ表現に、 プログラマブルさと、 静的検査と、 外部ファイルのインポートを加えたもの 5 / 18
Dhallはチューリング完全ではない 具体的にはループがない どうやっても無限ループしないので安心 (個人的には) 設定記述にはループがない方が読みやす い気がする ユニットテストにはあまりループを書くべきでないと いうのと近い 6 /
18
例: Kubernetes(オリジナルYAML) 1 kind: Service 2 apiVersion: v1 3 metadata:
4 name: my-service 5 spec: 6 selector: 7 app: MyApp 8 ports: 9 - protocol: TCP 10 port: 80 11 targetPort: 9376 (https://kubernetes.io/docs/concepts/ services-networking/service/) 7 / 18
例: Kubernetes(型注釈なしDhall) 1 { kind = 2 "Service" 3 ,
apiVersion = 4 "v1" 5 , metadata = 6 { name = "my-service" } 7 , spec = 8 { selector = 9 { app = "MyApp" } 10 , ports = 11 [ { protocol = "TCP", port = 80, targetPort = 9376 } ] 12 } 13 } 8 / 18
DhallをYAMLに変換 > cat service.dhall | dhall-to-yaml apiVersion: v1 kind: Service
spec: selector: app: MyApp ports: - targetPort: 9376 protocol: TCP port: 80 metadata: name: my-service できたけど、これだけだと嬉しさが少ない “Service” などを typo してもエラーにならない 9 / 18
Dhallの機能を活用する Dhall の機能によって静的検査を導入してみる つまり、Dhall で Kubernetes のスキーマを記述する スキーマは k8s_types.dhall という名前で別ファ
イルに切り出す 以下の便利な標準関数を使う constructors: Union 型のコンストラクタを生成する merge: Union 型の値を任意の型に変換する 10 / 18
例: Kubernetes(Dhall色々定義1/2) 1 let Kind_ = < Service : {}
| Pod : {} | Deployment : {} > 2 3 in let kindHandlers = 4 { Service = 5 λ(_ : {}) → "Service" 6 , Pod = 7 λ(_ : {}) → "Pod" 8 , Deployment = 9 λ(_ : {}) → "Deployment" 10 } 11 12 in let ApiVersion = < v1 : {} > 13 14 in let apiVersionHandlers = { v1 = λ(_ : {}) → "v1" } 15 16 in let Metadata : Type = { name : Text } 17 18 in let Selector : Type = { app : Text } 19 20 in let Protocol = < TCP : {} | UDP : {} > 21 22 in let protocolHandlers = { TCP = λ(_ : {}) → "TCP", UDP = λ(_ : { (次のページに続く) 11 / 18
例: Kubernetes(Dhall色々定義2/2) 24 in let Port : Type = {
protocol : Text, port : Integer, targetPort : 25 26 in let Spec : Type = { selector : Selector, ports : List Port } 27 28 in let Yaml 29 : Type 30 = { kind : Text, apiVersion : Text, metadata : Metadata, spec 31 32 in { Kinds = 33 constructors Kind_ 34 , kind = 35 λ(k : Kind_) → merge kindHandlers k 36 , ApiVersions = 37 constructors ApiVersion 38 , apiVersion = 39 λ(v : ApiVersion) → merge apiVersionHandlers v 40 , Protocols = 41 constructors Protocol 42 , protocol = 43 λ(p : Protocol) → merge protocolHandlers p 44 , Yaml = 45 Yaml 46 } 12 / 18
例: Kubernetes(Dhall版Ver.2) 1 let types = ./k8s_types.dhall 2 3 in
( { kind = 4 types.kind (types.Kinds.Service {=}) 5 , apiVersion = 6 types.apiVersion (types.ApiVersions.v1 {=}) 7 , metadata = 8 { name = "my-service" } 9 , spec = 10 { selector = 11 { app = "MyApp" } 12 , ports = 13 [ { protocol = 14 types.protocol (types.Protocols.TCP {=}) 15 , port = 16 80 17 , targetPort = 18 9376 19 } 20 ] 21 } 22 } 23 : types.Yaml 24 ) 13 / 18
DhallをYAMLに変換(Ver.2) > cat service_typed.dhall | dhall-to-yaml apiVersion: v1 kind: Service
spec: selector: app: MyApp ports: - targetPort: 9376 protocol: TCP port: 80 metadata: name: my-service 結果を変えずに静的検査・関数・インポートが追加で きた! 14 / 18
Dhallのツールチェイン dhall コマンド Dhall のインタプリタ。ターミナル上で Dhall ファイル のチェックをするならこれ dhall-format コマンド
Dhall の公式フォーマッタ。保存時に自動で走るように しておくと良い (Emacs の dhall-mode は勝手にそうして くれる) 15 / 18
Dhallのアプリケーション dhall-json dhall-to-json, dhall-to-yaml コマンドを提供 Dhall ファイルを JSON/YAML に変換する すでに
JSON/YAML を使うアプリがあるなら、これを 使って静的検査と関数とインポートのある Dhall から JSON/YAML を生成しよう dhall-to-cabal Dhall ファイルを cabal ファイルに変換する Dhall を本格利用するならノウハウの宝庫なので、cabal に興味がない場合でも参考にするとよい 16 / 18
バインディング プログラミング言語から Dhall を読む場合は各言語のバ インディングを利用する すでに提供されている: Haskell, Nix1 開発中: Scala,
Rust 1正確にはプログラミング言語ではない 17 / 18
事例紹介 18 / 18