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.

From Java To Clojure

1,421 views

Published on

JavaプログラマこそClojureを始めよう!
cf. English version:
https://www.slideshare.net/KentOhashi/from-java-to-clojure-english-version

Published in: Software
  • Be the first to comment

From Java To Clojure

  1. 1. JavaからClojureへ - Adieu Java -
  2. 2. 自己紹介 lagénorhynque /laʒenɔʁɛ̃k/ (defprofile lagénorhynque :name "Kent OHASHI" :account @lagenorhynque :company 株式会社オプト :languages [Clojure Haskell Python Scala English français Deutsch русский] :interests [プログラミング 語学 数学])
  3. 3. Lisp × Java
  4. 4. 言語としてのJava
  5. 5. 言語としてのJavaの問題点 関数型プログラミング(FP)サポートの不足 もっとFPしたい! (OOP要素も静的型付けも必須ではない) 冗長なシンタックス もっとシンプルに書きたい! 柔軟性/拡張性の不足 もっと自由に書きたい!
  6. 6. 独断と偏見によるJVM言語比較 factor Java Groovy Scala Kotlin Clojure FP support × △ ◯ △ ◯ simplicity × ◯ △ ◯ ◎ exibility × ◯ ◯ ◯ ◎
  7. 7. Clojure を使えば、 言語としての Java とはお別れできる!! Adieu, Java ! Javaともこれで本当にお別れだね(;_;)/~~~
  8. 8. What is Clojure?
  9. 9. Clojureの名前の由来 Clojure is pronounced exactly like closure, where the s/j has the zh sound as in azure, pleasure etc. The name was chosen to be unique. I wanted to involve c (c#), l (lisp) and j (java). Once I came up with Clojure, given the pun on closure, the available domains and vast emptiness of the googlespace, it was an easy decision. ― Rich Hickey, creator of Clojure cf. meaning and pronunciation of Clojure
  10. 10. Clojure /ˈkloʊʒɚ/ ※ NOT /ˈkloʊd͡ʒɚ/ element meaning /ˈkloʊʒɚ/ クロージャ(closure), 関数型プログラミング C C#(.NET) as a platform, .NET言語 l Lisp方言 j Java as a platform, JVM言語
  11. 11. 1. FP言語としてのClojure 2. Lisp方言としてのClojure 3. JVM言語としてのClojure
  12. 12. FP言語としてのClojure
  13. 13. イミュータブルなList, Vector, Map, Set, etc. user=> '(1 2 3) (1 2 3) user=> [1 2 3] [1 2 3] user=> {:a 1 :b 2 :c 3} {:a 1, :b 2, :c 3} user=> #{1 2 3} #{1 3 2}
  14. 14. 高階関数(filter, map, reduce, etc.) user=> (def xs [1 2 3]) #'user/xs user=> (filter odd? xs) (1 3) user=> (map #(* % %) xs) (1 4 9) user=> (reduce + 0 xs) 6 user=> (reduce + 0 (map #(* % %) (filter odd? xs))) 10 user=> (->> xs #_=> (filter odd?) #_=> (map #(* % %)) #_=> (reduce + 0)) 10
  15. 15. ちなみに、 #( ) は #(* % %) ↓↓↓ (fn [x] (* x x)) に相当するリーダマクロ
  16. 16. ちなみに、 ->> は (->> a (f x) (g y) (h z)) ↓↓↓ (h z (g y (f x a))) に展開されるマクロ(threading macroの一種)
  17. 17. 遅延シーケンス user=> (def nats (iterate inc 0)) #'user/nats user=> (take 10 nats) (0 1 2 3 4 5 6 7 8 9) user=> (take-while #(< % 10) nats) (0 1 2 3 4 5 6 7 8 9)
  18. 18. Lisp方言としてのClojure
  19. 19. S式( )S-expressions (f a b c ...) f: 関数, マクロ, 特殊形式 a, b, c, ...: 引数 cf. Java f(a, b, c, ...)
  20. 20. 関数/メソッドの定義も // Java public void greet(String name) { System.out.println("Bonjour, " + name + " !"); } S式 ;; Clojure (defn greet [name] (println (str "Bonjour, " name " !")))
  21. 21. 名前空間/パッケージの宣言もインポートも // Java package demo_app; import java.io.IOException; import java.util.ArrayList; import java.util.List; S式 ;; Clojure (ns demo-app.core (:import (java.io IOException) (java.util ArrayList List)))
  22. 22. first(≒ car), rest(≒ cdr), cons, ... user=> (def xs [1 2 3]) #'user/xs user=> (first xs) 1 user=> (rest xs) (2 3) user=> (cons 0 xs) (0 1 2 3)
  23. 23. S式のコードはそのままデータとして扱える (code as data; )homoiconicity user=> (first '(def xs [1 2 3])) def user=> (rest '(def xs [1 2 3])) (xs [1 2 3]) user=> (cons 'def '(xs [1 2 3])) (def xs [1 2 3]) user=> (eval (cons 'def '(xs [1 2 3]))) #'user/xs
  24. 24. Lispマクロ 強力なコンパイル時メタプログラミング機構 user=> (defmacro unless ; clojure.core/if-not マクロを再実装しただけ #_=> ([test then] #_=> `(unless ~test ~then nil)) #_=> ([test then else] #_=> `(if (not ~test) #_=> ~then #_=> ~else))) #'user/unless user=> (unless (= 1 2) :ok) :ok user=> (macroexpand '(unless (= 1 2) :ok)) (if (clojure.core/not (= 1 2)) :ok nil)
  25. 25. ちなみに、 関数定義のdefn は user=> (macroexpand #_=> '(defn greet [name] #_=> (println (str "Bonjour, " name " !")))) (def greet (clojure.core/fn ([name] (println (str "Bonjour, " name " !"))))) 特殊形式def, fn を利用したマクロ
  26. 26. 大量の括弧を扱うのがつらい? ⇒Lisp編集用プラグインがあれば非常に快適 The Animated Guide to Paredit Parinfer - simpler Lisp editing
  27. 27. JVM言語としてのClojure
  28. 28. Javaのclassファイルにコンパイル jarとして実行可能 $ lein new app demo-app Generating a project called demo-app based on the 'app' template. $ cd demo-app/ $ lein uberjar Compiling demo-app.core Created /Users/lagenorhynchus/code/demo-app/target/uberjar/demo-app-0.1.0-SNAPSHOT.jar Created /Users/lagenorhynchus/code/demo-app/target/uberjar/demo-app-0.1.0-SNAPSHOT-standalone.jar $ java -jar target/uberjar/demo-app-0.1.0-SNAPSHOT-standalone.jar Hello, World!
  29. 29. Javaメソッドの呼び出し staticメソッド // Java Integer.parseInt("123") ;; Clojure (Integer/parseInt "123") インスタンスメソッド // Java "a b c".split("s") ;; Clojure (.split "a b c" "s")
  30. 30. 破壊的な初期化/設定 // Java java.util.Map<String, Integer> m = new java.util.HashMap<>(); m.put("a", 1); m.put("b", 2); m.put("c", 3); return m; ;; Clojure (doto (java.util.HashMap.) (.put "a" 1) (.put "b" 2) (.put "c" 3))
  31. 31. メソッドチェーン // Java new StringBuilder() .append("a") .append("b") .append("c") .toString() ;; Clojure (.. (StringBuilder.) (append "a") (append "b") (append "c") toString) ;; または (-> (StringBuilder.) (.append "a") (.append "b") (.append "c") .toString)
  32. 32. JavaコレクションAPIとの連携 Javaのコレクション→ Clojureの関数 user=> (def xs (doto (java.util.ArrayList.) #_=> (.add 1) #_=> (.add 2) #_=> (.add 3))) #'user/xs user=> (class xs) java.util.ArrayList user=> xs [1 2 3] user=> (map inc xs) (2 3 4)
  33. 33. Clojureのコレクション→ Javaのメソッド user=> (def xs [1 2 3 4 5]) #'user/xs user=> (class xs) clojure.lang.PersistentVector user=> (instance? java.util.List xs) true user=> (.subList xs 1 4) [2 3 4]
  34. 34. cf. Google Sheets API (Java版)の利用例 // Java public Integer duplicateWorksheet(Sheets sheets, String spreadsheetId, Integer worksheetId, Strin List<Request> reqs = Arrays.asList( new Request().setDuplicateSheet( new DuplicateSheetRequest().setSourceSheetId(worksheetId) .setNewSheetName(worksheetName) .setInsertSheetIndex(1) ) ); return executeUpdate(sheets, spreadsheetId, worksheetId, reqs) .getReplies() .get(0) .getDuplicateSheet() .getProperties() .getSheetId(); } ;; Clojure (defn duplicate-worksheet [sheets spreadsheet-id worksheet-id worksheet-name] (let [reqs [(-> (Request.) (.setDuplicateSheet (-> (DuplicateSheetRequest.) (.setSourceSheetId worksheet-id) (.setNewSheetName worksheet-name) (.setInsertSheetIndex (int 1)))))]] (-> (execute-update sheets spreadsheet-id worksheet-id reqs) .getReplies first .getDuplicateSheet .getProperties .getSheetId)))
  35. 35. ほかにも core.async transducers clojure.spec ClojureScript etc.
  36. 36. Clojure なら FPとLispとJavaの力を引き出して もっとシンプルに、もっと自由に、プログラミングできる!!
  37. 37. Vive les S-expressions ! S式万歳!
  38. 38. Further Reading : Clojure公式 : Clojureのビルドツール : Clojureのビルドツール : ClojureのオンラインREPLのひとつ : ClojureScriptのオンラインREPLのひとつ 第7章Clojure Clojure Leiningen Boot Try Clojure Replumb REPL 『7つの言語7つの世界』 『プログラミングClojure 第2版』

×