27
Clojure入門 Kouhei Mikami

Programming Clojure

Embed Size (px)

Citation preview

Page 1: Programming Clojure

Clojure入門Kouhei Mikami

Page 2: Programming Clojure

Clojureとは

●S式で書くプログラミング言語●Lispの親戚●関数型言語●JVM上で動く

● Javaのライブラリの呼び出しが可能

Page 3: Programming Clojure

Clojureを学ぶと何故よいか

●S式で記述●Lispの親戚●関数型言語●JVM上で動く

● Javaのライブラリの呼び出し

Page 4: Programming Clojure

関数型言語の分類

● 非純粋関数型言語(Clojureを含むLisp)● 変数の書き換えが可能

● 純粋関数型言語(Haskellなど)● 変数の書き換えが一切できない、というか変数が無い● 状態という概念を持たない● I/O処理などもモナドを使ってうまくやる(らしい)

Page 5: Programming Clojure

Clojureの構文

(println “Hello” “World”)

Page 6: Programming Clojure

関数型言語とは

● 関数が第一級オブジェクト● 生成/代入/演算/引数or戻り値としての使用」が可能● Javaはクラスが第一級オブジェクト

Page 7: Programming Clojure

Clojureの構文

(println “Hello” “World”)

関数 引数1 引数2

Page 8: Programming Clojure

四則演算

(+ 1 2) => 3

(- 5 2) => 3

(* 10 10) => 100

(/ 8 2) => 4

Page 9: Programming Clojure

複雑な四則演算

(+ 2 (- 5 2)) => 5

(* (/ 4 2) (+ 1 2)) => 6

(- 5 4 3 2 1) => -5

Page 10: Programming Clojure

Boolean型

(> 1 2) => false

(= 5 5) => true

Page 11: Programming Clojure

if文

(if 条件 式)

(if (> 5 2) “OK”) => “OK”(if (= 5 2) “OK”) => nil

(if 条件 式1 式2)

(if (= 5 2) “OK” “NO”) => “NO”

Page 12: Programming Clojure

andとor

(if (and (= 5 5) (= 1 2)) “OK” “NO”)=> “NO”

(if (or (= 2 2) (= 1 2)) “OK” “NO”)=> “OK”

Page 13: Programming Clojure

関数の定義

(defn 関数名 [引数] 式)

例1:引数aと引数bを足した値を返す(defn test-method [a b] (+ a b))

Page 14: Programming Clojure

値の束縛

変数の定義ではなく、値の束縛という(def 名前 値)

例:aaaに1を束縛する(def aaa 1)

Page 15: Programming Clojure

無名関数

名前の無い関数を作ることができる(fn [引数] 式)

例:map関数に無名関数を渡して、Vectorのすべての要素に適用

(map (fn [n] (* n n)) [1 2 3]) => [1 4 9]

Page 16: Programming Clojure

基本的な構文の解説は終わり

Page 17: Programming Clojure

2章 シーケンス

Page 18: Programming Clojure

シーケンスとは

●Clojureの基本となるデータ構造●「最初の要素」と「その残り」で分けることが可能●その種類

● Vector : [1 2 3]● Map : {:Apple 100 :Orange 200}● List : (1 2 3)● String, XML, 他...

Page 19: Programming Clojure

firstとrest

● first関数 : シーケンスの先頭要素を取得する● (first [1 2 3]) => 1● (first {:a 1 :b 2 :c 3}) => {:a 1}

● rest関数 : シーケンスの先頭要素の残りを取得する● (rest [1 2 3]) => [2 3]● (rest {:a 1 :b 2 :c 3}) => {:b 2 :c 3}

Page 20: Programming Clojure

シーケンスと再帰

● シーケンスを使うと再帰が容易になる● 例:シーケンスの中身をすべて加算する関数

(defn test-recur [seq]

(if (empty? seq)

0

(+ (first seq) (test-recur (rest seq)))

Page 21: Programming Clojure

シーケンスと汎用性

● Vector, List, Map, Set...すべてがシーケンスのInterfaceを実装しているので汎用性が高い

● 例 : filter関数● 元のシーケンスから要素を選び出して新しいシーケンス

を作る

(filter even? [1 2 3 4 5]) => (2 4)

(filter #(!= % \a) “abc”) => (\b \c)

(filter #(even? (first (rest (first %)))) {:a 1 :b 2 :c 3} => {:b 2}

Page 22: Programming Clojure

遅延評価

● repeat関数 : 引数が1つの場合, 無限に続く引数の数のシーケンスを作成する● (repeat 1) => (1 1 1 1 1 1....)

● 必要に応じて評価を実行する● (take 5 (repeat 1))● このとき、5個の1を生成する評価は実行されるが6個目以降は実行されていない

● SQL文の実行などを遅延評価で必要に応じて実行したりするらしい

Page 23: Programming Clojure

不変性

● シーケンスの値は絶対に変わらない● シーケンスに要素を追加(cons)したとき、新しい

シーケンスが作成される● (cons 0 [1 2 3]) => [0 1 2 3]● このとき、返却される値として新しく[0 1 2 3]が作られる● ただし、物理的に新しく作られるわけではない。可能な

限りデータを共有する

Page 24: Programming Clojure

3. マクロ

Page 25: Programming Clojure

マクロとは

●コードを実行時に別のコードに置き換える機能●評価の順番をコードからいじることが出来る●Clojure(Lisp)の中核をなす仕組み●マクロの一例 :

● defun● and / or● Monad● Javaの呼び出し (. getHoge getFuga)

●S式が使われているのはマクロの為と言って良い

Page 26: Programming Clojure

関数とマクロの違い

● unlessマクロの作成● if(!isHogeHoge) {...}はやりたくない● (unless 条件 式) : 条件がfalseのとき、式を実行する

関数バージョン(うまくいかない)

(defn unless [expr form]

(if expr nil form))

(unless true (println “AAA”)) => AAA nil

=> 関数に渡す前に評価してはダメ

Page 27: Programming Clojure

マクロバージョン

(defmacro unless [expr form]

(list 'if expr nil form))

(unless (= 1 2) (+ 3 4))

(if (= 1 2) nil (+ 3 4))

=> 展開するものが無くなったとき、それを特定の位置に置換する