てっしーの雑記

主に技術系のネタを

Clojure言語メモ

先月参加したフロントエンド勉強会でも登場したClojure ついていけなかったので改めて学習をしようと思い言語メモとして書いて覚えようという魂胆です chichi1091.hatenablog.jp

基本的に他サイトの写経なので読み飛ばしていただいてOKです^^;

関数の呼び出し

(関数 引数1 引数2 ・・・) で呼び出す

user=> (+ 1 2)
3
user=> (println "Hello World")
Hello World
nil

def

他言語の代入に近い

user=> (def x 3)
#'user/x    ; xに3が入る
user=> (def y (+ x 1))
#'user/y    ; 3 + 1の結果がyに入る
user=> (println y)
4
nil

defn

関数の定義
(defn 関数名 [引数] (処理))

user=> (defn hello []
  #_=> (println "hello"))
#'user/hello
user=> (hello)
hello
nil

user=> (defn sum-3 [a b c]
  #_=> (+ a b c))
#'user/sum-3
user=> (sum-3 1 2 3)
6

可変な引数持つ関数

引数の数に応じて実行する処理を分ける

user=> (defn switch
  #_=> ([] (println "no args"))
  #_=> ([x] (println "x:" x))
  #_=> )
#'user/switch
user=> (switch)
no args
nil
user=> (switch 1)
x: 1
nil

& で可変の引数が受け取れる

user=> (defn args [& args]
  #_=> (println args))
#'user/args
user=> (args 1 2 3)
(1 2 3)
nil

無名関数

fn [引数] (処理) で名前のない関数を定義できる

user=> ((fn [a b c] (* a b c)) 1 2 3)
6

let

狭い範囲での変数定義

user=> (let [x 3
  #_=> y 4]
  #_=> (println x y))
3 4
nil
user=> (println x y)
; 参照できない
CompilerException java.lang.RuntimeException: Unable to resolve symbol: x in this context, compiling:(null:1:1) 

四則演算

; 加算
user=> (+ 1 2)
3
; 除算
user=> (- 2 1)
1
; 乗算
user=> (* 1 2)
2
; 除算
user=> (/ 4 2)
2

データの型

数値

; +1する
user=> (inc 1)
2
; 最小
user=> (min 3 4 5)
3
; 最大
user=> (max 3 4 5)
5

文字列

user=> "ABC"
"ABC"
; 文字列連結
user=> (str "Hello" "World")
"HelloWorld"

文字

user=> \a
\a

キーワード

user=> :abc
:abc
user=> :123
:123

真偽値とnull

user=> true
true
user=> false
false
user=> nil
nil

コレクション

リスト

user=> '(1 2 3 4 5)
(1 2 3 4 5)

ベクター

複数の要素を格納できる

user=> [1 2 3]
[1 2 3]
user=> [:a "hoge" 999]
[:a "hoge" 999]

マップ

Key:Value連想配列

user=> {:id 1 :name "hoge"}
{:id 1, :name "hoge"}
; カンマで見やすくすることも可能
user=> {:id 1, :name "hoge"}
{:id 1, :name "hoge"}

セット

重複がないコレクション

user=> #{1 2 3}
#{1 3 2}
user=> #{:a :b :c}
#{:c :b :a}

遅延シーケンス

user=> (range 1 4)
(1 2 3)
user=> (repeat 3 :a)
(:a :a :a)

分岐

user=> (def x 3)
#'user/x
user=> (if (> x 0)
  #_=> (println "over zero")
  #_=> (println "under zero or eq zero")
  #_=> )
over zero
nil

; do で処理をまとめることができる
user=> (def x -1)
#'user/x
user=> (if (> x 0)
  #_=> (do
  #_=> (print "over "))
  #_=> (print "zero"))
  #_=> (do
  #_=> (print "not over "))
  #_=> (print "zero"))
  #_=> )
not over zero
nil

; 偽判定
user=> (if-not (> x 0)
  #_=> (println "not"))
not
nil

; cond
user=> (cond
  #_=> (> x 0) (println "over zero")
  #_=> (= x 0) (println "equal zero")
  #_=> :else (println "under zero"))
under zero
nil

; condp
user=> (def x 1)
#'user/x
user=> (condp = x
  #_=> 1 (println "1")
  #_=> 2 (println "2")
  #_=> 3 (println "3")
  #_=> :else (println "other"))
1
nil

繰り返し

user=> (for [x [1 2 3]]
  #_=> (* x 2))
(2 4 6)

; 偶数のものだけを10個取り出す
user=> (take 10 (for [x (range)
  #_=> :when (even? x)] x))
(0 2 4 6 8 10 12 14 16 18)

; 遅延シーケンス
user=> (doall (for [x (range 10)] (println x)))
0
1
2
3
4
5
6
7
8
9
(nil nil nil nil nil nil nil nil nil nil)