From Java To Clojure (English version)

38
From Java To Clojure - Adieu Java -

Transcript of From Java To Clojure (English version)

Page 1: From Java To Clojure (English version)

From Java To Clojure- Adieu Java -

Page 2: From Java To Clojure (English version)

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])

Page 3: From Java To Clojure (English version)

Lisp × Java

Page 4: From Java To Clojure (English version)

Java as a language

Page 5: From Java To Clojure (English version)

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!

Page 6: From Java To Clojure (English version)

JVM language comparisonfrom my own point of view

factor Java Groovy Scala Kotlin Clojure

FP support × △ ◯ △ ◯

simplicity × ◯ △ ◯ ◎

�exibility × ◯ ◯ ◯ ◎

Page 7: From Java To Clojure (English version)

Using Clojure,

we can say goodbye to Java as a language!!

Adieu, Java !Now we have to say farewell to you, Java (;_;)/~~~

Page 8: From Java To Clojure (English version)

What is Clojure?

Page 9: From Java To Clojure (English version)

Origin of the name Clojure

Clojure is pronounced exactly like closure, wherethe s/j has the zh sound as in azure, pleasure etc.

The name was chosen to be unique. I wanted toinvolve c (c#), l (lisp) and j (java).

Once I came up with Clojure, given the pun onclosure, 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

Page 10: From Java To Clojure (English version)

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

Page 11: From Java To Clojure (English version)

1. Clojure as a FP language

2. Clojure as a Lisp dialect

3. Clojure as a JVM language

Page 12: From Java To Clojure (English version)

Clojure as a FP language

Page 13: From Java To Clojure (English version)

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}

Page 14: From Java To Clojure (English version)

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

Page 15: From Java To Clojure (English version)

BTW,

#( ) is

#(* % %)

↓↓↓(fn [x] (* x x))

a reader macro equivalent as above.

Page 16: From Java To Clojure (English version)

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.

Page 17: From Java To Clojure (English version)

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)

Page 18: From Java To Clojure (English version)

Clojure as a Lisp dialect

Page 19: From Java To Clojure (English version)

S-expressions

(f a b c ...)

f: function, macro, special forma, b, c, ...: arguments

cf. Java

f(a, b, c, ...)

Page 20: From Java To Clojure (English version)

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 " !")))

Page 21: From Java To Clojure (English version)

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

Page 22: From Java To Clojure (English version)

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)

Page 23: From Java To Clojure (English version)

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

Page 24: From Java To Clojure (English version)

Lisp macrospowerful 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)

Page 25: From Java To Clojure (English version)

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.

Page 26: From Java To Clojure (English version)

Hard to handle a lot of parentheses?

⇒ Lisp-editing plugins make it very comfortable

The Animated Guide to Paredit

Parinfer - simpler Lisp editing

Page 27: From Java To Clojure (English version)

Clojure as a JVM language

Page 28: From Java To Clojure (English version)

Compiling to Java class �lesexecutable 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!

Page 29: From Java To Clojure (English version)

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")

Page 30: From Java To Clojure (English version)

destructive initialisation/setting

// 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))

Page 31: From Java To Clojure (English version)

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)

Page 32: From Java To Clojure (English version)

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)

Page 33: From Java To Clojure (English version)

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]

Page 34: From Java To Clojure (English version)

cf. usage example of Google Sheets API (Java)

// Java public Integer duplicateWorksheet(Sheets sheets, String spreadsheetId, Integer worksheetId, String worksheetName) 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)))

Page 36: From Java To Clojure (English version)

If you use Clojure,with the power of FP, Lisp and Java

you can program more simply, more freely!!

Page 37: From Java To Clojure (English version)

Vive les S-expressions !

Long live S-expressions!

Page 38: From Java To Clojure (English version)

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)