プログラミング言語 Clojure の最大カンファレンスである clojure/conj に参加してきました。
年一回、世界中の Clojurian が集まって Clojure のアップデート、活用事例、ライブラリの紹介などのセッションを行います。動画は既に Clojure TV にアップロードされているため詳細には語りませんが雰囲気と気になったセッションを紹介します。
Day 0
今年の会場は Cognitect の所在する東海岸ノースカロライナ州ダラムという街でした。例年は大都市で開催されてきましたが今年は運営上の都合でこちらになったようです。ダラムは Duke 大学を始めとして世界的な学術機関が集積する「リサーチ・トライアングル」と呼ばれる地域の一角で、地元企業も多数参加していました。他には全米三大 BBQ の一つに数えられるカロライナスタイル(酸っぱ辛いソース)が有名です。
前夜は毎年恒例の Game Night。みんながお気に入りのボードゲームを持ち寄って遊びます。Rich Hickey がホストするゲームを観戦しましたが今年もルールを理解することは叶いませんでした。
気になったセッション
REBL: Stuart Halloway
Cognitect の Founder & President である Stuart Halloway による REBL(Read Eval Browse Loop) の初紹介セッション。
Clojure の最も強力なツールと言えば REPL(Read Eval Print Loop) ですが、Eval の結果は常に表示可能な "データ" とは限りません。またデータでも深い階層構造を持っていたり遅延シーケンスを含んでいたりすると REPL 上での表示は困難となります。REBL はそのような問題を解決するために開発されたデータブラウザで、データ化方法とナビゲート方法を定義することでそれらをブラウズできるように出来ます。それぞれ Datafieble(datafy) と Navigatable(nav) というプロトコルを実装することで任意の対象をブラウズ可能に拡張できます。
セッション後、早速 Early Access が公開されました。
https://github.com/cognitect-labs/REBL-distro
起動すると通常の REPL と同時に接続された JavaFX 製 REBL ブラウザが立ち上がります。REBL を主軸に開発するのは難しそうなので必要に応じて利用するという感じなりそうですが REPL の可能性を広げる素晴らしい発表でした。
Kafka and the REPL: Stream Processing, the Functional Way: Charles Reese
サンフランシスコで Clojure User Group を主催する Funding Circle による Clojure での Kafka 利用に関するセッション。
Funding Circle は企業間ローンサービスを提供する企業であり、マーケットプレイスの更改で Kafka を導入したそうです。Kafka のストリームプロセッサーを Clojure で開発するために jackdaw というラッパーライブラリを開発し、この日 OSS としてリリースしました。
Kafka のストリームプロセッシングには Clojure のイミュータブルデータ構造や REPL 有効で、かつ Java との相互運用性が必要なので Clojure を採用したそうです。最近 Kafka の話をよく聞いていたので試してみようと思います。
Re-usable GUI Components with Re-frame and Atomic Design: Mark Nutter
re-frame でアトミックデザインを実現するというセッション。
re-frame とアトミックデザインの説明をした後で、実際に作ったアトミックデザインカタログを披露しました。re-frame でアトミックデザインを実現するには、re-frame はアプリケーション状態を一元管理するため、状態を持つコンポーネントをどう作るかが味噌となります。これには色々な実現方法がありますが、この人は生成時に "パス" を設定することで、一元管理された状態に対するサブスクリプションを自分自身で生成する "Self-aware" なコンポーネントとして作る方法を取っていました。
re-frame でフォーム値をどう管理するかは各々微妙に違う方法を取っているので、紹介された方法を試してみようかと思いました。
Declarative Domain Modeling for Datomic Ion/Cloud: Tiago Luchini
40 以上のプロダクトを送り出してきたというエンジニアによる、Datomic Cloud/Ion を使った宣言的ドメインモデリングのセッション。
理想的には、システムとはロジック、状態、モデルを引数に取る関数として記述できるべきです。
system = fn(logic, state, model)
logic = fn_1...fn_n
state = fn(state_init, txs)
model = fn(model_domain, model_mech)
これを Clojure の世界で実現するなら、ロジックは関数、状態は Datomic となりますが、モデルはどうすればよいのか、というのがこの人のセッションの主題です。この人の考えではモデルは宣言的な記述であるべきで、そこから Clojure のロジックや状態に適合したスキーマを生成できるのが望ましいとのことです。そのために DSL から clojure.spec や Datomic, GraphQL のスキーマを生成出来るドメインモデリングライブラリを開発したそうです。
また Clojure の関数は Datomic Ion、Datomic は Datomic Cloud でサーバレスに構築できるので、Hodur でドメインモデリングをすれば短期間でシステム開発が可能となります。デモでは実際に可視化しながらドメインモデリングを披露し、Ion にデプロイして GraphQL API が動くところまでを見せてくれました。Ion はどう使うのか、Lambda との違いなどにも触れてくれているので Datomic Ion が気になっている人も動画を見てみて下さい。
Maybe Not: Rich Hickey
Clojure 開発者である Rich Hickey による、Null/Option をシステムでどう扱うべきかについてのセッション。
毎年恒例?の Haskell ディスから始まり、関数の引数、返り値に対するオプショナリティは付け外しに関して対称であるべきで Haskell の Maybe は付け外しが呼び出し側にとって破壊的な変更になるのでまずいと言っています。
一方、clojure でも clojure.spec におけるデータ記述に問題があるといっています。spec では現状、データの必須、オプションを下記のように記述します。
(spec/def ::car (spec/keys :req [::make]
:opt [::model ::year]))
しかし、何が必須で何がオプショナルかは呼び出しのコンテキストによって変わります。車を引数に取る関数群は本質的には同様に "車" を引数に受け取るべきで、何が "必須か" だけが変わるべきだと。そのためそれらは分離されるべきで、そのために spec/keys は、"車" を RDF 的に記述する spec/schema とコンテキストにおける必須項目を記述する spec/select に書き換えるつもりだそうです。
;; spec/schema によるスキーマの指定
(spec/def ::addr (spec/schema [[::street ::city ::state ::zip]]))
(spec/def ::user (spec/schema [[::id ::first ::last ::addr]]))
;; 違うコンテキストにおける必須・オプショナリティの指定
;; ::user スキーマは再利用可能
;; 文法は仮(検討中)
(get-movie-times user =>
(spec/select ::user [::id ::addr {::addr [::zip]}]))
(place-order user =>
(spec/select ::user [::first ::last ::addr {::addr [::street ::city ::state ::zip]}]))
かなり大きな変更になるとは思いますが、同じエンティティに対してオプショナリティの違う spec をいくつも書くことに違和感があったためこれでスッキリしそうです。
Robust APIs with clojure.spec & GraphQL: Lily Goh + Dom Kiva-Meyer
Clojure/Script, React/Native, GraphQL を使ったコンサルタントで、Y-Combinator のスタートアップなどとも協業している二人による、GraphQL と clojure.spec で堅牢な API を開発するというセッション。
clojure のデータリテラルを利用して宣言的に GraphQL と spec のスキーマ生成を行うことで、柔軟かつ高機能な API 開発でき、更にフロントエンド精査にも活用しているとのこと。そのための serene というライブラリを開発したそうです。
この系統のライブラリは前述の Hodur 然りやや乱立している気がしますが、GraphQL スキーマと API を 100% カバーできているというのが強みなのかと思います。
AWS, meet Clojure: David Chelimsky
Cognitect の David による新しい Clojure の AWS API の紹介セッション。
Clojure から aws-java-sdk やラッパーライブラリの amazonica を使うとオブジェクト指向なインターフェースを使わなくてはいけなかったり、ドキュメントを探すのが難しいといった問題があります。また、直接 pure Clojure なライブラリを作っても、増え続ける AWS サービスに対応するのは困難です。
Cognitect ではこれらの問題を解決するために、AWS の Endpoint, Service Descriptor から自動生成するというアプローチの新たな Clojure AWS API ライブラリを開発していたようです。ライブラリは AWS のサービス単位で分かれており、かつ生成のタイミングでバージョンが切られていくので最新のサービスに追従していくことが可能です。下記のような感じで利用できます。
(require '[cognitect.aws.client.api :as aws])
;; クライアント作成
(def s3-client (aws/client {:api :s3}))
;; 実行
(aws/invoke s3-client {:op :ListBuckets})
また、問題だったドキュメントも関数から取得できたり、引数が正しいかの精査ができたり、バックオフ指定やリトライ、非同期実行などもサポートしています。リポジトリは下記で公開されました。
conj 時点でまだアルファ版ですが、Cognitect 謹製だけあって Clojure の強みを味わえる作りになっており、是非使ってみたいと思いました。
Party REPL — A multi-player REPL built for pair-programming: Tomomi Livingstone + Hans Livingstone
ペアプログラミング用 REPL の紹介と、Atom プラグイン開発に関するセッション。
モダンなエディタは Atom の TeleType の様にペアプログラミング用の機能を持っています。Paty REPL は TeleType をベースに REPL を共有しながらペアプログラミングを行えるツールだそうです。実際にアプリケーションはホスト側で稼働することになりますが、ゲストはそこに接続して REPL の履歴を共有しながらコマンドを送信することが出来ます。
現状は Linux/Mac に対応しており、leiningen で起動した unrepl, nrepl, socket repl が使えるそうです。
やはり Atom というところが Clojurian に普及するネックとなりそうですがペアプログラミングのパラダイムを変える非常に強力なツールで今後が楽しみです。ちなみにデモをした二人は夫婦で、二人共日本語話せます。
Can you GAN?: Carin Meier
Cognitect の Carin は GAN のセッションでした。
Generative Adversarial Networks (GANs) は、画像を生成する Generator と画像が本物か見破る Discriminator という二つの学習モデルを競い合わせることで、本物と見分けのつかない画像を生成する深層学習手法です。Apache MXNet は多言語に対応した深層学習フレームワークで、AWS が公式にサポートしており、Carin の発案により Clojure API もサポートしています。
GAN を使って生成した Flan(GAN と音でかけたプリンみたいなお菓子)を披露してくれました。MXNet は Clojure API を使うことで宣言的に学習パラメータを記述できるので使いやすそうです。
Learning and Teaching Clojure on the job at Amperity: Dave Fetterman
数十人の Clojure エンジニアが在籍するという Amperity における Clojure 教育・学習環境についてのセッションです。
Amperity は開発の 95% を Clojure で行っているという筋金入りの Clojure 企業ですが、入社してくる人の殆どは Clojure 経験が大してなく、三ヶ月のオンボーディングを行って Clojure エンジニアを育てているそうです。最も力を入れていることは Clojure を共に学ぶ環境創りで、特に全員が意見を持ち合うことが大切だと言っていました。
また、Clojure 学習環境を作るツール類もいくつか紹介していました。
- Admin REPL
- OSS ではないが適当なクライアントライブラリを読み込ませた REPL をサーバに常時起動しており、誰でもすぐに接続して試せる環境を用意している。
- lein-monolith
- 複数のサブプロジェクトをモノリスにローカルに構築できる leiningen プラグインにで、サービス全体構成を理解しやすくしている。
- greenlight
- 宣言的なテスト記述と、データとしての結果が得られる結合テスト用ライブラリを開発しており、テストをドキュメントとして理解できるようにしている。
Amperity は Seattle で Seajure という Clojure meetup を主催しているそうなので、行く機会があれば顔を出してみて下さい。
Probabilistic programming and meta-programming in Clojure: Vikash Mansinghka
MIT の研究者による Probabilistic Programming に関するセッション。
Probabilistic Programming(確率的プログラミング?)は厳密な数学的手法では解けない問題を確率的に解決する手法らしいです。Metaprob という Clojure ベースのメタ言語を開発しており、これと BQL という SQL 風言語を使うことでシンプルに Probabilistic Programming を実現できるそうです。
深層学習に近い問題を解決する別の手段だそうで、知らない世界だったので興味深かったです。
Every Clojure Talk Ever: Alex Engelberg and Derek Slager
締めは前述の Clojure オンボーディングをやってる Amperity によるセッション。
ぶっちゃけ Clojure コミュニティ / conj 参加者の内輪ネタで、会場は大爆笑でした。起動しない REPL を作り込んだり、ネタライブラリ公開していたり、芸が細かい。笑
まとめ
気になったセッションを紹介しました。触れなかった、参加しなかったセッションでも、Thoughtworks の Chif Tech Officer によるキーノート、Clojure を初心者向けのプログラミング言語にするべく REPL エラーメッセージの改善に取り組む大学での取り組みや、病院での活用事例、Java プラットフォームのセッションなど盛り沢山な内容でした。
改めて感じたのは Clojure の活用される範囲の広さで、それぞれの場所で単純に Clojure が使えるということ以上の価値を生み出しているのが素晴らしいなと感じました。