Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Clojureの世界と実際のWeb開発

Clojureの特徴と、実際のウェブ開発時に使ってる機能や手法などなど。

  • Login to see the comments

Clojureの世界と実際のWeb開発

  1. 1. オブジェクト指向とは まったく違うClojureの世界と 実際のWeb開発 2018年6月 矢野勉
  2. 2. だれ? 名前: 矢野勉 twitter: t_yano github: tyano 会社とか: 代表取締役社長 SPEEDA Japan Company プロダクト開発チーム社員 ↑実はいま京都で学生バイト(プログラマ)orプロの開発者募集してます 興味あればどうぞ。
  3. 3. だれ? 開発関係とか: 以前は: Javaメインでやってました。 最近は: 主にClojureメインでやってます 業務もClojureのタスクが中心です。 Clojureのオープンソースのプロジェクトにパッチを送ったり、 Clojure本体の方でもバグ修正のチケット送ったりしてます。
  4. 4. ブログ http://boxofpapers.hatenablog.com
  5. 5. Clojureって聞いたことないな? ・LISP系のプログラミング言語 ・実用寄り! ・Common LISPとかeLispは手続き寄りの言語だけど、Clo ・ホスト言語に乗っかった実装(JVM) ・データは原則としてすべて不変 ・コレクションはだいたい遅延シーケンス https://clojure.org
  6. 6. 不変データをmapとかfilterで加工し ていくことでプログラムを作る Data Data Datamap filter
  7. 7. JVM言語? JVMはホスト言語の一つ ほかにも、Javascriptをホスト言語にしたClojureとか 、.NET CLRをホストにしたClojureがある JVM版に機能が追加されると、ほかのClojureにもち ゃんと機能追加される https://clojurescript.orgClojureScript ClojureCLR https://github.com/clojure/clojure-clr
  8. 8. 特徴 まあ、カッコは目立ちますよね… でも、他の言語と比べてカッコが多いわけじゃないんです!
  9. 9. シンプルな言語仕様 [ ] ベクタ。配列。 { } マップ。連想配列 ( ) 関数呼び出し or 連結リスト #{ } セット
  10. 10. シンプルな言語仕様 (my-great-fn arg1 arg2) 特に注釈がなければ、かっこ ( ) はすべて関数呼び出しです my-great-fn(arg1 arg2) よくあるこれと同じです。
  11. 11. データと関数は はっきり別れている データにメソッドが生えているわけではない データは常に単なるデータであり、それを処理する関数は 何個あってもいいし、 どこにあってもいいし、 誰でも定義できる
  12. 12. “It is better to have 100 functions operate on one data structure than to have 10 functions operate on 10 data structures” 10種類のデータ構造にそれぞれを扱う 10個の関数があるよりも、ひとつのデー タ構造を扱う100個の関数がある方が良 い
  13. 13. 共通のデータ構造 Seq Associative いわゆる「リスト」のようなもの。「先頭」と「残り」で繋がっているなにか。 いわゆる「マップ」「連想配列」のようなもの。キーと値で構成されたもの 多くの関数はこのいずれかを引数に受け取り、 このいずれかを返します First Rest
  14. 14. RDBの結果セット 多くの言語ではResultとかResultSetとかなんらかのクラスが定義されてますが ClojureではただのMapです。 結果セット特有の処理は別途関数として用意すればいいだけなので、 メソッドを生やすためだけにデータ型を定義する必要はないです ただのMapなので、多くのClojure関数がそのまま適用できます。
  15. 15. 静的型付けではない ものを定義できるけど、関数はそれらをSeqかAssociativeとして ードで示すために、型ではなく述語を使ったClojure Specとい
  16. 16. データは不変 データは不変だから、プログラム(関数)のやるこ とは、何か不変データを受け取って、それを変換し て返すこと。 ひたすらそれだけ。
  17. 17. ウェブAPIは関数 比喩ではなく ClojureでのWeb API開発では、APIハンドラとは、「 リクエスト」というデータを受け取って 「レスポンス」というデータを返す単なる関数として 実装します。 だからテストを書くのも簡単。 だって本当にただの関数だから、サーバも必要ない。
  18. 18. REPL Driven Development ただの関数だから、ソースをREPLにロードするだけでいつでも実行できる! 関数は引数にしか依存しない コンテナなどの起動が必要ない なんでもREPLに転送してすぐ実行確認しちゃうから テストを書くのが億劫になる問題が…
  19. 19. Web API仕様 Ring https://github.com/ring-clojure/ring PythonのWSGI、RubyのRackのような、HTTPリクエストを処理する仕様 Javaで言えばServlet仕様のようなもの?
  20. 20. Ring仕様 HTTPサーバ (Jetty/http-kit/Alephなどなど) リクエスト・ルーター (Compojure/Ataraxy/Bidiなど) あなたの書いたリクエスト処理関数 Ring Middleware Ring仕様の上にライブラリが 作られている
  21. 21. Ringの定めていること • 大雑把にまとめると、リクエストを処理する「ハンドラ 」関数の引数(リクエスト)と戻り値(レスポンス)の 仕様 • リクエストとレスポンスはただのマップであり、どうい うキーを持っているべきかを定めている • cookieもheaderもパラメータも、sessionすらも、リクエ ストマップのキーに過ぎない
  22. 22. Ring Middleware リクエストマップを受け取って、マップを書き換え て次のハンドラを呼ぶようなただの関数 HandlerMiddlewareMiddlewareMiddleware
  23. 23. Request Map だいたい以下のようなキーが付いているただのマップ ただし、自由にキーを追加できるので、これだけとは限らない :server-port :server-name :remote-addr :uri :query-string :scheme :request-method :protocol :ssl-client-cert :headers :body :session :cookies
  24. 24. REPL Demo
  25. 25. みんなREPLでコードをガンガン動かしながらプログラムを作っていくので、 REPL開発を支援するIDE機能や ライブラリが発展しています 名前空間にJack Inしたり 変更済みファイルをREPL内で再ロードしたり システム全体をREPLから再起動したり 書いている関数ブロックを丸ごとREPLに転送したり
  26. 26. いま人気があるのは Micro Framework Duct 定義に従ってシステムを依存関係に 合わせて構築したり、ぜんぶ停止したり、一部を変更して再構築したりする 機能を備えています SpringのAutowire、DIみたいな依存性解決だけを抜き出した感じ https://github.com/duct-framework/duct
  27. 27. 次は。 遅延シーケンス Lazy Sequence
  28. 28. Clojureのリスト処理関数の大半 は、遅延シーケンスを作ります map filter repeat reduce constantly
  29. 29. 無限シーケンスが簡単にできる (iterate inc 0) 0から始めて、1ずつ上がっていく数値の無限シーケンス
  30. 30. 遅延シーケンスは、要素を取得す ることでその部分が実体化する (take 5 (iterate inc 0)) ;; => (0 1 2 3 4) (実際には効率化のために30個程度まとめて実体化されるケースもあります) 1ずつ上がる数値列の先頭5つを取り出す
  31. 31. 例えば: (->> (iterate inc 0) (map (fn [v] (println "val = " (* v 2)) v))) 無限の数列だけど、map関数に副作用が入っている(コンソールに値を出力する) take関数などで値を取り出さない限り、コンソールには何も出力されません
  32. 32. これを利用すれば すべては遅延実行されるので RDBへちょっとずつクエリを投げて、最終的に全部 を取るような遅延シーケンス 外部APIからoffset/limitを使って適時データを取って くる遅延シーケンス このように、いろんなものを「遅延シーケンス」という抽象として扱えます。 遅延シーケンスはSeqなので、 共通データ構造Seqを扱えるどの関数でも使えます。
  33. 33. ぜんぶこの構造に乗せられる seq seq seqmap filter
  34. 34. Clojureでは遅延シーケン スを使いこなすのが肝です 。
  35. 35. プログラムとは、あるデータからリ スト(seq)を作ってmapしたりfilterし たりreduceしたりするもの Clojureでは つまりは 全体がデータ変換関数という だと捉えることができます
  36. 36. ウェブアプリケーションは リクエストマップを受け取って、 レスポンスマップに変換する データ変換関数 関数 リクエスト レスポンス
  37. 37. Simple なんでもSeqかAssociative リクエストをレスポンスに変換する関数を書くだけ REPLでガンガン試す シンプル過ぎて迷うことがあんまりないのです。
  38. 38. ウェブアプリ用技術 Compojure リクエストルーター http-kit Clojure製HTTPサーバ Duct アプリケーションのリソース依存関係定義・構築フレームワー ク Buddy セキュリティ・ライブラリ パスワード暗号化関数や、認証認可のためのRing Middlewareなどの集まり Cheshire JSONパーサ clj-http httpクライアント clojure.java.jdbc RDB接続
  39. 39. IDE
  40. 40. 現状、 Emacs + CIDER が一番人気です。 すでにEmacsに慣れている人はこれでいいと思う。 Emacs苦手な人!ほかにもあります。
  41. 41. • Emacs用のライブラリ • REPL Driven支援が豊富 • CIDER Jackinで、開発プロジェクトに潜り込む形でREPLを起動できる • リファクタ機能あり • ソースの定義元へのジャンプとか。 the Clojure(Script) Interactive Development Environment that Rocks!
  42. 42. Spacemacs + Clojure Layer Vimmerは Clojure layer入れると、CIDERも使えます。 vimの皮を被ったEmacs
  43. 43. IDEをくれ! IntelliJ IDEA + Cursive CursiveはIDEA Plugin。商用開発利用は有料です。 (仕事で使うものなんだから金を払おう!) CIDERではないけど、REPL制御もできるし、当然リファクタやソースジャンプ なども、IDEAの操作でできます。
  44. 44. この3つのどれかを選 ぶのがいいと思います
  45. 45. どのIDEかよりも 大事なこと
  46. 46. Structural Editing 文字ではなく構造を編集する
  47. 47. Clojure(LISP)プログラマは括 弧を道具として使います Clojureのコードには、シンプルな構造がある (defn calc-age [birthday] (let [today (now) diff (:year (difference birthday today))] diff)) つまり、括弧です。
  48. 48. 構造を編集する Slurp(吸い込む) (if has-item?) (do-something arg1 arg2) ;=> (if has-item? (do-something arg1 arg2)) Barf(追い出す) (let [birthday user-name]) ;=> (let [birthday] user-name) (if has-item? (do-something arg1 arg2)) Delete (if has-item?)→
  49. 49. Structural Editing自体は他の言語でもできるそうですが、 コード自体がリスト構造になっているClojureでは、これの活用で すごく効率が上がります 前述の3つの開発環境では、どれでもこの機能が使えるので、 ぜひ覚えてください (IDEごとに操作方法は異なります)
  50. 50. Clojureの特徴まとめ • シンプルな言語仕様 • (ほぼ)すべてが不変 • 共通データ構造に対してプログラムを書く • データと関数が分離することでいろいろシンプルになる • 遅延シーケンスでなんでもシーケンス化 • REPL Driven Programming • 非同期安全
  51. 51. 本当は今日話したかったけど 時間の関係で話せなかったこと 拡張可能な言語Clojure マクロやdeftypeによって、新しい構文を作れる 実は非同期もすごいんです core.asyncを使えば、go-routine/軽量プロセスもいけるんです。
  52. 52. Q&A

×