622 Views
October 09, 20
スライド概要
Clojureらしい内部DSLの開発方法について簡単に紹介。
"simple"なアプローチでDSLを作ろう!
「楽しく楽にcoolにsmartに」を理想とするprogrammer/philosopher/liberalist/realist。 好きな言語はClojure, Haskell, Python, English, français, русский。 読書、プログラミング、語学、法学、数学が大好き! イルカと海も大好き🐬
で作る"simple"なDSL Clojure
lagénorhynque (defprofile lagénorhynque :id @lagenorhynque :reading "/laʒenɔʁɛ̃ k/" :aliases [" "] カマイルカ🐬 :languages [Clojure Haskell English français] :interests [programming language-learning law mathematics] :commits ["github.com/lagenorhynque/duct.module.pedestal" "github.com/lagenorhynque/duct.module.cambium"] ["github.com/japan-clojurians/clojure-site-ja"]) :contributes
系⾔語で(内部)DSLといえばマクロを使うもの? マクロを定義すると コンパイル前にコード(AST)を⾃在に変換し 評価を制御することができる マクロ⾃体は rst-class objectではないので composabilityが損なわれる Lisp
コミュニティではマクロ定義は控えめ 「マクロ・クラブ」のルール 1. マクロを書くな 2. それがパターンをカプセル化する唯⼀の ⽅法ならば、マクロを書け cf. 『プログラミングClojure 第2版』 Clojure data > functions > macros data-driven, data-oriented なものを好む
コミュニティでは"simple"であることを重視 Simple Made Easy (Rich Hickeyのプレゼン) ⼀⾔でいえば、"simple"に設計しよう "simple"とは単⼀の役割/責務のみを上 ⼿く果たすこと cf. UNIX哲学 "complex"にするのを避けて"simple"なもの を組み合わせよう Clojure
な の例 data-driven DSL
のテンプレート: HTML
ReactのJSXに相当するテンプレート
Reagent
(defn some-component []
[:div
[:h3 "I am a component!"]
[:p.someclass
"I have " [:strong "bold"]
[:span {:style {:color "red"}} " and red"]
" text."]])
Honey SQL: SQL (def sqlmap {:select [:a :b :c] :from [:foo] :where [:= :f.a "baz"]}) ※開発予定 の ⾵⾔語 に対するDSL cf. lagenorhynque/honeysoql Salesforce SQL SOQL
bidi: ルーティングDSL (def routes ["/" {"index.html" :index "articles/" {"index.html" :article-index [:id "/article.html"] :article}}])
cf. Compojure: マクロベースのルーティングDSL (defroutes app (GET "/" [] "<h1>Hello World</h1>") (route/not-found "<h1>Page not found</h1>"))
malli: バリデーションスキーマ (def Address [:map [:id string?] [:tags [:set keyword?]] [:address [:map [:street string?] [:city string?] [:zip int?] [:lonlat [:tuple double? double?]]]]])
だと何がうれしい? Clojureでプログラム的に⾃由に操作できる ⾔語機能と標準ライブラリでそのまま扱える read (parse)も print もそのままできる Clojureデータはclojure.specで仕様を記述で きる Clojureデータとしてどのように表現し、ど のように変換/解釈するかだけに集中できる 問題も"simple"になる data-driven
参考: edn形式 edn (extensible data notation) リテラル(のサブセット)によるシリア ライゼーションフォーマット ClojureにとってのS式表現 ベクター、マップ、セットなどもある JavaScriptにとってのJSON相当 タグによる拡張も可能(extensible) Clojureとはedn形式で表現されたデータを扱う ことに特化した⾔語ともいえる(?) Clojure
Further Reading Clojure/ClojureScript 関連リンク集 - Qiita Data > Functions > Macros. But why? - LispCast