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
超変換! Hiccup data structure!!
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
ayato
August 31, 2017
Programming
670
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
超変換! Hiccup data structure!!
ayato
August 31, 2017
More Decks by ayato
See All by ayato
マイクロサービス内で動くAPIをF#で書いている
ayato0211
1
1.6k
Clojureという言語が私逹にもたらしたもの
ayato0211
6
3.2k
3年間考え続けてきたWebアプリケーションにおけるテストの話
ayato0211
3
310
Re:REPL-Driven Development
ayato0211
3
1.4k
Meta Template Engine
ayato0211
2
1.2k
About Integrant
ayato0211
0
610
Muscle Assert
ayato0211
0
330
Clojureを用いたWebアプリケーション開発
ayato0211
2
3.2k
翻訳にまつわるエトセトラ
ayato0211
6
1.3k
Other Decks in Programming
See All in Programming
Embedded SREと共に達成した会員管理システムのAWS移行 - SRE NEXT 2026 ランチスポンサーセッション
niftycorp
PRO
0
1.4k
20260623_Loop Engineeringで自分の分身の問い合わせBotを作る
ryugen04
0
160
Developing with AI Agents — Codex, Claude Code & Cowork Practical Guide
x5gtrn
PRO
0
1.3k
AI 輔助遺留系統現代化的經驗分享
jame2408
1
1.2k
TypeScript+Orvalで実現する型安全かつ堅牢でスケーラブルなマルチチャネル通知基盤 / TSKaigi Night talks ~after conference~
d0riven
0
390
コーディングルールの鮮度を保ちたい for SRE NEXT 2026 / keep-fresh-go-internal-conventions-sre-next-2026
handlename
0
120
決定論的オーケストレーションの設計と実装 / Design and Implementation of Deterministic Orchestration
nrslib
4
1.6k
ADKを使って簡単にAIエージェントを作ってみよう
k1mu21
0
290
Vite+ Unified Toolchain for the Web
naokihaba
0
690
Claude Opus 4.6以後の受託開発エンジニアの変化(Claude Code開発ノウハウ大公開スペシャルbyクラスメソッド)
iidatakuma
1
340
Observability in Practice:Grafana 與 Edge Device SRE 的那些事
blueswen
0
190
【やさしく解説 設計編・中級 #1】一つの車に、運転手は一人 ~ある倉庫システムの事例から~
panda728
PRO
0
110
Featured
See All Featured
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
460
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
760
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
3.7k
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
260
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
870
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
10k
Build your cross-platform service in a week with App Engine
jlugia
234
18k
Fashionably flexible responsive web design (full day workshop)
malarkey
408
66k
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
180
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
1
2.8k
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
220
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
600
Transcript
Hiccup Data Structure!! Lisp Meet Up presented by Shibuya.lisp #55
超変換!!
–Johnny Appleseed ʠ͜͜ʹҾ༻Λೖྗ͍ͯͩ͘͠͞ɻʡ –Yusuke Godai “こんなやつらのために、 これ以上誰かの涙は⾒たくない! 皆に笑顔でいて欲しいんです! だから⾒ててください!俺の…変⾝!! ”
–Johnny Appleseed ʠ͜͜ʹҾ༻Λೖྗ͍ͯͩ͘͠͞ɻʡ –@ayato-p “HTML Formのために、 これ以上誰かの涙は⾒たくない! Hiccupユーザーに笑顔でいて欲しいんです! だから⾒ててください!俺の…変換!! ”
あやぴー •ayato-p@github •Cybozu Startups, Inc. •Clojureエンジニア •Webアプリを作るお仕事 •仮面ライダーと言えばクウ◦世代 •ガンダムと言えばS◦ED世代
今日の話
今日話すこと •そもそもHiccupとは •HTMLフォームを書くのが面倒だということ •Hiccupデータの変換について •ClojureScriptでマクロ展開するときハマった話 •「仮面ライダーク◦ガ」の素晴らしさについて
今日話すこと •そもそもHiccupとは •HTMLフォームを書くのが面倒だということ •Hiccupデータの変換について •ClojureScriptでマクロ展開するときハマった話 •「仮面ライダーク◦ガ」の素晴らしさについて
Hiccup
そもそもHiccupとは •HTMLをClojureのデータ構造で表現するDSL •ベクタをタグ、マップを属性として表現する •Clojureコミュニティでは人気(?) •沢山のライブラリがHiccup-likeなデータでの表現を サポートしている •例) Enlive, Reagent, Rum,
Instaparse, etc
そもそもHiccupとは [:a#mybtn.button {:href "..."} "..."] タグベクター: ベクタで表現したHTMLタグ
そもそもHiccupとは [:a#mybtn.button {:href "..."} "..."] タグ名: CSSセレクターのように書ける
そもそもHiccupとは [:a#mybtn.button {:href "..."} "..."] 属性: マップで表現
そもそもHiccupとは [:a#mybtn.button {:href "..."} "..."] コンテンツ: タグベクターや文字列を書ける
これであなたも ✨Hiccupマスター✨
HTMLフォームを 書くのは面倒だ
HTMLフォームは面倒 •フォームのポスト処理に失敗した場合、入力されていた 値を入力された状態にして再描画しなければいけない •利用しているCSSフレームワークのルールにそって、 エラーが適切に表示されるようにしなければならない •全てのHTMLフォームを全く同じように表示したくない ことがある •例) ログインフォーム、グリッドスタイル
[:div.form-group [:label {:for "input-email"} "Email address"] [:input#input-email.form-control {:type :email :name
:email :class (when (contains? errors :email) "is-invalid") :value (:email values) :placeholer "Enter email"}] [:div.invalid-feedback (:email errors)] [:small.form-text.text-muted "We'll never share your email with anyone else."]] Bootstrap4の場合
[:div.form-group [:label {:for "input-email"} "Email address"] [:input#input-email.form-control {:type :email :name
:email :class (when (contains? errors :email) "is-invalid") :value (:email values) :placeholer "Enter email"}] [:div.invalid-feedback (:email errors)] [:small.form-text.text-muted "We'll never share your email with anyone else."]] Bootstrap4の場合
…
どうにかしたい… 1.諦める 2.小さい関数で面倒なところをラップする (hiccup.formみたいな) 3.Formativeみたいなフォーム用ライブラリを使う (jkk/formative) 4.まだ見たこと無い解決方法
OOPな言語のWAFだと… •フォームに値をマッピングするのに •フォームオブジェクトをつくる •ORMのモデルオブジェクトをつかう •エラー用クラスを付与するのに •カスタムタグをつくる •エラー時に固定のCSSクラスを付与する
–Johnny Appleseed ʠ͜͜ʹҾ༻Λೖྗ͍ͯͩ͘͠͞ɻʡ –Yusuke Godai “求められた気がしたんです。 あの蜘蛛みたいな奴と戦えって!”
–Johnny Appleseed ʠ͜͜ʹҾ༻Λೖྗ͍ͯͩ͘͠͞ɻʡ –@ayato-p “求められた気がしたんです。 あのVerbose Hiccupと戦えって!”
Kuuga
Kuugaとは •Pure Clojureにしか依存していない •ユーザーが自由に •任意のタグやクラスに対して変換ルールを定義できて •マクロ展開時に変換することもできて •ClojureScriptもサポートしている •Hiccupのようなデータを変換するライブラリ •https://github.com/ayato-p/kuuga
変換ルールを書く-その) (defmethod growing/transform-by-tag :input [_ options tag-vector] (let [[tagkw tagopts
contents] (tool/parse-tag-vector tag-vector)] `[~tagkw (update-input-opts ~options ~tagopts) ~@contents]))
変換ルールを書く-その* (defmethod growing/transform-by-class :form-group [_ options tag-vector] (let [[tagkw tagopts
contents] (tool/parse-tag-vector tag-vector) contents (reduce (fn [contents' tagvec'] (let [[tk to _] (tool/parse-tag-vector tagvec') [_ t] (tool/parse-tag-keyword tk)] (cond-> (conj contents' tagvec') (= t "input") (conj `(invalid-fb ~options ~to))))) [] contents))] `[~tagkw ~tagopts ~@contents]))
こうすると…
これを… [:div.form-group [:label {:for "input-email"} "Email address"] [:input#input-email.form-control {:type :email
:name :email :placeholder "Enter email"}] [:small.form-text.text-muted "We'll never share your email with anyone else."]]
こんな感じで展開できる [:div.form-group [:label {:for "input-email"} "Email address"] [:input#input-email.form-control {:type :email
:name :email :class (when (contains? errors :email) "is-invalid") :value (:email values) :placeholder "Enter email"}] [:div.invalid-feedback (:email errors)] [:small.form-text.text-muted "We'll never share your email with anyone else."]] ※イメージです
Kuugaのメリット •マクロ展開時に変換できる •なので実行時の変換コストがない •特別なタグ/記法を覚える必要がない •どのくらい変換ルールを書くかもユーザー次第
Kuugaのデメリット •特にない •マクロ展開時に変換するルールを書くのが少し難しい •実行時に変換する方法は速度があまり出ない
KuugaとClojureScript
Kuugaは… •マクロ展開時にHiccupデータを変換できる •拡張ルールをマルチメソッドで記述する •ClojureScriptをサポートしている
ClojureScriptでのマクロ •ClojureScriptでマクロは書けない •セルフホストはとりあえず忘れる •マクロ展開はClojureの環境が利用される •展開後のフォームに含まれるものはClojureScript上に なければならない
問題. •マクロ展開時に利用されるマルチメソッドはClojureの 環境で定義されていなければならない
問題. •マクロ展開時に利用されるマルチメソッドはClojureの 環境で定義されていなければならない •ClojureScriptのビルド時に変換ルールを読み込んで おかないといけない
解決策 •cljsbuildなどの既存のツールに任意のClojure libを 読み込む仕組みがなさそう? •自前でスクリプトを書いて、その中で任意のlibを 読み込みClojureScriptのビルドAPIを直接叩く •lein-execはプロジェクトの環境を引き継げる •Bootは元々そういう用途で使えるので便利 https://github.com/ayato-p/kuuga/blob/master/examples/cljs/script/cljsbuild.clj
まとめ •Kuugaを使うとわりとハッピーになれる(気がした) •マクロ展開時に分かっている部分を変換するコンセプト を適用できるところは他にもある気がする •SQL Builder的なやつとか