Clojureメモ:forを使う
Clojureを始めて1週間ちょいといったところか。 とりあえず本を読んでいる、ちょくちょく試してみている感じ。
ループのまわし方とかも、手続き型プログラミングと勝手が違って戸惑う。
※Clojureのforは命令型言語のforループとは違うらしい。(リスト内包表記と呼ばれる。)
forの一番シンプルな例。
user=> (for [i [0 1 2 3]] (println i)) 0 1 2 3 (nil nil nil nil)
最後の(nil ...)
は関数の返り値をREPL環境が表示している。
(for ...)
は制御文ではなく関数なので戻り値がある。
(for ...)
はつまり、ループ分だけ要素があるコレクションを作って返すということか。
さて、ループをまわすには、要はまず何かの集合が必要だということだな。
上記の例だと、集合[0 1 2 3]
の中から一個ずつアイテムを取り出してi
に代入し、それを使って処理している。
(Clojureの用語だとシンボルi
に値をバインドする、と言う。)
上記はClojureのベクター(要は配列)を使ったが、次にマップを使ってみる。
user=> (def a {:m1 1 :m2 2}) #'user/a
user=> a {:m1 1, :m2 2}
user=> (for [i a] (println i)) [:m1 1] [:m2 2] (nil nil)
おお、期待通りの動作。マップの順番って定義された順だろうか・・・まあ、あとで調べるとしよう。
1から10の数字を表示する関数を書いてみる。
1〜10をまわすが、[1 2 ...]
で定義するのも面倒で、range
関数を使う。
user=> (range 1 11) (1 2 3 4 5 6 7 8 9 10)
でとりあえず、
user=> (for [i (range 1 11)] (println i)) 1 2 3 4 5 6 7 8 9 10 (nil nil nil nil nil nil nil nil nil nil)
てな感じだ。