TL;DR
- Clojure の
forはループではなくリスト内包表記で、結果を返す。doseqは副作用のある繰り返しに使い、何も返さない。 - 単にループさせるときは
loopを使い、recurで次のループに入る。
内容
for
Clojure の for は、他の言語の for ループではなく、リスト内包表記である。
(let [nums [1 2 3 4]]
(for [num nums]
(* num 10)))
;; [10 20 30 40]複数のシーケンスを渡すと、次のようにすべての組み合わせが実行される。
(def colors ["red", "blue", "green", "yellow"])
(def shapes ["square", "circle", "triangle", "rectangle"])
(for [color colors
shape shapes]
(str color " " shape));; 実行結果
;; ("red square" "red circle" "red triangle" "red rectangle"
;; "blue square" "blue circle" "blue triangle" "blue rectangle"
;; "green square" "green circle" "green triangle" "green rectangle"
;; "yellow square" "yellow circle" "yellow triangle" "yellow rectangle")doseq
doseq は、標準出力やファイルへの書き込み、メール送信、DB への書き込みなど、副作用のある繰り返し操作に使う。
for と似ているが、for が実行結果を返すのに対し、doseq は何も返さない。
(let [nums [1 2 3 4]]
(doseq [num nums]
(* num 10)))
;; nil次のように書くと、処理が実行されているのを確かめられる。
(let [nums [1 2 3 4]]
(doseq [num nums]
(println (* num 10))))
;; 10
;; 20
;; 30
;; 40
;; nilloop
単にループさせるときは、loop を使う。
(loop [x 1]
(when (<= x 5)
(println x)
(recur (inc x))));; 出力結果
;; 1
;; 2
;; 3
;; 4
;; 5[x 1] は、変数 x を 1 で初期化することを表す。(recur …) は次のループを再帰的に呼び出すための構文で、(inc x) で変数 x に 1 を足してから、次のループに入る。