Upload
kouhei-mikami
View
1.114
Download
0
Embed Size (px)
Citation preview
Clojure入門Kouhei Mikami
Clojureとは
●S式で書くプログラミング言語●Lispの親戚●関数型言語●JVM上で動く
● Javaのライブラリの呼び出しが可能
Clojureを学ぶと何故よいか
●S式で記述●Lispの親戚●関数型言語●JVM上で動く
● Javaのライブラリの呼び出し
関数型言語の分類
● 非純粋関数型言語(Clojureを含むLisp)● 変数の書き換えが可能
● 純粋関数型言語(Haskellなど)● 変数の書き換えが一切できない、というか変数が無い● 状態という概念を持たない● I/O処理などもモナドを使ってうまくやる(らしい)
Clojureの構文
(println “Hello” “World”)
関数型言語とは
● 関数が第一級オブジェクト● 生成/代入/演算/引数or戻り値としての使用」が可能● Javaはクラスが第一級オブジェクト
Clojureの構文
(println “Hello” “World”)
関数 引数1 引数2
四則演算
(+ 1 2) => 3
(- 5 2) => 3
(* 10 10) => 100
(/ 8 2) => 4
複雑な四則演算
(+ 2 (- 5 2)) => 5
(* (/ 4 2) (+ 1 2)) => 6
(- 5 4 3 2 1) => -5
Boolean型
(> 1 2) => false
(= 5 5) => true
if文
(if 条件 式)
(if (> 5 2) “OK”) => “OK”(if (= 5 2) “OK”) => nil
(if 条件 式1 式2)
(if (= 5 2) “OK” “NO”) => “NO”
andとor
(if (and (= 5 5) (= 1 2)) “OK” “NO”)=> “NO”
(if (or (= 2 2) (= 1 2)) “OK” “NO”)=> “OK”
関数の定義
(defn 関数名 [引数] 式)
例1:引数aと引数bを足した値を返す(defn test-method [a b] (+ a b))
値の束縛
変数の定義ではなく、値の束縛という(def 名前 値)
例:aaaに1を束縛する(def aaa 1)
無名関数
名前の無い関数を作ることができる(fn [引数] 式)
例:map関数に無名関数を渡して、Vectorのすべての要素に適用
(map (fn [n] (* n n)) [1 2 3]) => [1 4 9]
基本的な構文の解説は終わり
2章 シーケンス
シーケンスとは
●Clojureの基本となるデータ構造●「最初の要素」と「その残り」で分けることが可能●その種類
● Vector : [1 2 3]● Map : {:Apple 100 :Orange 200}● List : (1 2 3)● String, XML, 他...
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}
シーケンスと再帰
● シーケンスを使うと再帰が容易になる● 例:シーケンスの中身をすべて加算する関数
(defn test-recur [seq]
(if (empty? seq)
0
(+ (first seq) (test-recur (rest seq)))
シーケンスと汎用性
● 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}
遅延評価
● repeat関数 : 引数が1つの場合, 無限に続く引数の数のシーケンスを作成する● (repeat 1) => (1 1 1 1 1 1....)
● 必要に応じて評価を実行する● (take 5 (repeat 1))● このとき、5個の1を生成する評価は実行されるが6個目以降は実行されていない
● SQL文の実行などを遅延評価で必要に応じて実行したりするらしい
不変性
● シーケンスの値は絶対に変わらない● シーケンスに要素を追加(cons)したとき、新しい
シーケンスが作成される● (cons 0 [1 2 3]) => [0 1 2 3]● このとき、返却される値として新しく[0 1 2 3]が作られる● ただし、物理的に新しく作られるわけではない。可能な
限りデータを共有する
3. マクロ
マクロとは
●コードを実行時に別のコードに置き換える機能●評価の順番をコードからいじることが出来る●Clojure(Lisp)の中核をなす仕組み●マクロの一例 :
● defun● and / or● Monad● Javaの呼び出し (. getHoge getFuga)
●S式が使われているのはマクロの為と言って良い
関数とマクロの違い
● unlessマクロの作成● if(!isHogeHoge) {...}はやりたくない● (unless 条件 式) : 条件がfalseのとき、式を実行する
関数バージョン(うまくいかない)
(defn unless [expr form]
(if expr nil form))
(unless true (println “AAA”)) => AAA nil
=> 関数に渡す前に評価してはダメ
マクロバージョン
(defmacro unless [expr form]
(list 'if expr nil form))
(unless (= 1 2) (+ 3 4))
↓
(if (= 1 2) nil (+ 3 4))
=> 展開するものが無くなったとき、それを特定の位置に置換する