LoginSignup
6
2

More than 5 years have passed since last update.

Clojure 頑張る

Last updated at Posted at 2018-09-02

1. 関数

1-1. 匿名関数

JS でいうところの x => x + 1 は、Clojure では #(+ 1 %) となり、x => x % 2 === 0 は、#((= 0 (rem % 2)) となる:

(map #(+ 1 %) [1 2 3]) ; => (2 3 4)
(filter #(= 0 (rem % 2)) [1 2 3]) ; => (2)

1-2. 関数合成 / 関数適用

comp で関数合成するもいいけど as-> マクロで上から順に次々適用させていくので十分なことが多い。なお、引数位置がうまくそろうなら ->, ->> の方がよりコンサイス:

(def comped (comp 
  (partial reduce *)
  (partial map inc)))
(comped (range 3)) ; => 6

(as-> (range 3) input
  (map inc input)
  (reduce * input)) ; => 6

(->> (range 3)
  (map inc)
  (reduce *)) ; => 6

seq に関数をどんどん適用していく際は transduce も便利

(def xf (comp
  (map inc)
  (take 3)
))
(transduce xf + (range)) ; => 6

1-3. 再帰

アリティオーバロードによる関数定義は再帰と相性が良い:

(defn rprint
  ([]
      (rprint 5))
  ([num]
      (println num)
      (if (> num 0)
        (recur (dec num)))))
(rprint) ; => 5 4 3 2 1 0が順に出力

loop を使えば関数定義なしで再帰できる:

(loop [num 5]
  (println (str "now:" num))
  (if (> num 0)
    (recur (dec num)))) ; => 5 4 3 2 1 0が順に出力

2. データ構造

2-1. Map

Mapのキーは通常 keyword と呼ばれるのを使う。keyword はMapのゲッター関数にもなるというなかなかイカれた仕様があるので、Map のキーにするのに最適:

(def hmap {:id 1, :name "alice", :score 20})
(hmap :id) ; => 1
(:id hmap) ; => 1

(def hmaps [{:id 1} {:id 2} {:id 3}])
(map :id hmaps) ; => (1 2 3)

Map も map できる。(key value) のペアに mapper をかます:

(map identity {:one 1 :two 2}) ; ([:one 1] [:two 2])

2-2. volatile & atom

volatile は時々刻々変化する値を参照する。それに加え、並列性を意識した機能を持つのが atom。swap! はいわゆる cas(check and swap) なのでアトミックな操作となり並列性が担保される:

(def counter (volatile! 100))
@counter ;=> 100
(vswap! counter inc) ; => 101
(vreset! counter 0) ;=> 0
@counter ;=> 0

(def counter (atom 100))
@counter ;=> 100
(swap! counter inc) ; => 101
(reset! counter 0) ;=> 0
@counter ;=> 0

3. 構造化

3-1. 名前空間

通常ファイル冒頭に ns マクロで名前空間の宣言をするのでそこで利用する他の名前空間を列挙する。REPLとかでは、 require + :as とかで簡易にアクセスするのもあり。便利なチートシートを読む

REPLで利用.clj
(clojure.string/join " " (range 3)) ; => "0 1 2", 直接使う

(require '[clojure.string :as s])
(s/join " " (range 3)) ; => "0 1 2", alias で使う
使われる側util.clj
(ns cl.util
    (:require [clojure.string :as s]))

(defn atjoin [x]
    (s/join "@" x))
使う側core.clj
(ns cl.core
  (:require [cl.util :as util])
  (:gen-class))

(defn -main [& args]
 ; 略
)

(util/atjoin (range 3)) ; => "0@1@2"

4. Misc

4-1. Windows

JRE
JRE は Oracle サイトからインストーラをポチポチやるとインストールされる上、PATHに登録される。java -versionで動作することを確認。

leiningen
PATHの通るところに、lein.bat を配置して lein self-install コマンドを打てば入るとのことだが、SSL証明書周りでエラーが出るというのがFAQ。エラーメッセージに対処策が書かれている(curlの設定をコマンドラインで変更)。lein new app <name> でプロジェクトを作って動作確認。

VSCode&PlugIns
エディタは VSCode をインストーラでポチポチやって終了。そして、 clojureVSCode というプラグインをインストールする。leiningen で作ったプロジェクトディレクトリを VSCode で開いて、clj な拡張子をダブルクリックすると勝手に REPL を起動して接続する(左下に接続中とかのステータスがでる)

コーディング
編集作業。コード片をREPLに送るのが基本だが、Ctrl+Shift+Pで出現するコマンドパレットにおいて、Clojure: Eval and Showというコマンドを入力すれば、評価される。お好みでショートカットキーに登録。直近の式だけを評価する方法がない気がする。

参考

というか私の勉強ソース

6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2