Slide 1

Slide 1 text

From Java To Clojure - Adieu Java -

Slide 2

Slide 2 text

Self-introduction /laʒenɔʁɛ̃k/ lagénorhynque (defprofile lagénorhynque :name "Kent OHASHI" :account @lagenorhynque :company "Opt, Inc." :languages [Clojure Haskell Python Scala English français Deutsch русский] :interests [programming language-learning mathematics])

Slide 3

Slide 3 text

Lisp × Java

Slide 4

Slide 4 text

Java as a language

Slide 5

Slide 5 text

Problems with Java as a language lack of functional programming (FP) support More FP! (OOP and static typing are not necessary) verbose syntax More simplicity! lack of exibility/extensibility More freedom!

Slide 6

Slide 6 text

JVM language comparison from my own point of view factor Java Groovy Scala Kotlin Clojure FP support × △ ◯ △ ◯ simplicity × ◯ △ ◯ ◎ exibility × ◯ ◯ ◯ ◎

Slide 7

Slide 7 text

Using Clojure, we can say goodbye to Java as a language!! Adieu, Java ! Now we have to say farewell to you, Java (;_;)/~~~

Slide 8

Slide 8 text

What is Clojure?

Slide 9

Slide 9 text

Origin of the name 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

Slide 10

Slide 10 text

Clojure /ˈkloʊʒɚ/ * NOT /ˈkloʊd͡ʒɚ/ element meaning /ˈkloʊʒɚ/ closure, functional programming C C#(.NET) as a platform, .NET language l Lisp dialect j Java as a platform, JVM language

Slide 11

Slide 11 text

1. Clojure as a FP language 2. Clojure as a Lisp dialect 3. Clojure as a JVM language

Slide 12

Slide 12 text

Clojure as a FP language

Slide 13

Slide 13 text

Immutable 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}

Slide 14

Slide 14 text

Higher-order functions (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

Slide 15

Slide 15 text

BTW, #( ) is #(* % %) ↓↓↓ (fn [x] (* x x)) a reader macro equivalent as above.

Slide 16

Slide 16 text

BTW, ->> is (->> a (f x) (g y) (h z)) ↓↓↓ (h z (g y (f x a))) a macro (a kind of threading macros) expanded as above.

Slide 17

Slide 17 text

Lazy sequences 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)

Slide 18

Slide 18 text

Clojure as a Lisp dialect

Slide 19

Slide 19 text

S-expressions (f a b c ...) f: function, macro, special form a, b, c, ...: arguments cf. Java f(a, b, c, ...)

Slide 20

Slide 20 text

Even a function/method de nition // Java public void greet(String name) { System.out.println("Bonjour, " + name + " !"); } is an S-expression. ;; Clojure (defn greet [name] (println (str "Bonjour, " name " !")))

Slide 21

Slide 21 text

Even namespace/package declaration and imports // Java package demo_app; import java.io.IOException; import java.util.ArrayList; import java.util.List; are S-expressions. ;; Clojure (ns demo-app.core (:import (java.io IOException) (java.util ArrayList List)))

Slide 22

Slide 22 text

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)

Slide 23

Slide 23 text

S-expression code can be treated as data (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

Slide 24

Slide 24 text

Lisp macros powerful compile-time metaprogramming facility user=> (defmacro unless ; just a reimplementation of clojure.core/if-not macro #_=> ([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)

Slide 25

Slide 25 text

BTW, defn used for function de nition user=> (macroexpand #_=> '(defn greet [name] #_=> (println (str "Bonjour, " name " !")))) (def greet (clojure.core/fn ([name] (println (str "Bonjour, " name " !"))))) is a macro composed of def, fn special forms.

Slide 26

Slide 26 text

Hard to handle a lot of parentheses? ⇒ Lisp-editing plugins make it very comfortable The Animated Guide to Paredit Parinfer - simpler Lisp editing

Slide 27

Slide 27 text

Clojure as a JVM language

Slide 28

Slide 28 text

Compiling to Java class les executable as a 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!

Slide 29

Slide 29 text

Calling Java methods static methods // Java Integer.parseInt("123") ;; Clojure (Integer/parseInt "123") instance methods // Java "a b c".split("\\s") ;; Clojure (.split "a b c" "\\s")

Slide 30

Slide 30 text

destructive initialisation/setting // Java java.util.Map 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))

Slide 31

Slide 31 text

method chaining // Java new StringBuilder() .append("a") .append("b") .append("c") .toString() ;; Clojure (.. (StringBuilder.) (append "a") (append "b") (append "c") toString) ;; or (-> (StringBuilder.) (.append "a") (.append "b") (.append "c") .toString)

Slide 32

Slide 32 text

Interoperating with Java collection API Java collection → Clojure function 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)

Slide 33

Slide 33 text

Clojure collection → Java method 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]

Slide 34

Slide 34 text

cf. usage example of Google Sheets API (Java) // Java public Integer duplicateWorksheet(Sheets sheets, String spreadsheetId, Integer worksheetId, Strin List 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)))

Slide 35

Slide 35 text

Furthermore, core.async transducers clojure.spec ClojureScript etc.

Slide 36

Slide 36 text

If you use Clojure, with the power of FP, Lisp and Java you can program more simply, more freely!!

Slide 37

Slide 37 text

Vive les S-expressions ! Long live S-expressions!

Slide 38

Slide 38 text

Further Reading : Clojure o cial site : Clojure build tool : Clojure build tool : Clojure online REPL : ClojureScript online REPL Chapter 7: Clojure Clojure Leiningen Boot Try Clojure Replumb REPL Seven Languages in Seven Weeks Programming Clojure (2nd edition)