Clojure完全にマスターした話

TL;DR

  • LeiningenインスコしてIntelliJ IDEAにCursiveプラグイン入れるとLeiningenで生成したプロジェクト普通に読み込めるし括弧辺りの問題もだいぶ快適になるよ。
  • テスト環境何もしなくてもとりあえず整ってるっぽい
  • 完全にマスターとはHelloWorldやったり普通のFizzBuzzやったり出来た、を指す隠語

経緯

最初の一歩

Clojureのサイトからzip落としてきて展開、中に clojure-1.7.0.jar が入ってるので

java -cp clojure-1.7.0.jar clojure.main

するとREPLが起動していろいろ試せる

REPLがしょぼい

矢印キーが効かなかったり履歴機能が無かったりとにかく何を書くにもだるいなって思ってたらrlwrapというのがあるよと教えてもらいました。
よく分かんないですけどうまいことラップしていい感じにしてくれるとのこと。

rlwrap java -cp clojure-1.7.0.jar clojure.main

と言う感じでREPL起動すると履歴がついたり矢印キー使えたりしていい感じになりました。
rlwrapのインスコ方法は調べてください。だいたいパッケージマネージャで入ると思います。

Leiningenのインスコ

Javaで言う所のMavenScalaで言う所のactivator(sbt)みたいなものらしいです。ライブラリの依存関係やってくれたり、プロジェクトの雛形作ってくれたりコンパイルしたりしてくれる、Clojure界ではみんな当然使っている奴という感じっぽいです。
インスコは適当なディレクトリで

wget https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein

して、DLしたファイルにパス通せば終わりです

Cursiveインスコ

IntelliJ IDEAのClojureプラグインです。
勝手に括弧の対応取ってくれたり対応する括弧に色んな色付けてくれたり補完出してくれたりLeiningenと連携してくれたりしてClojureコーディングライフを強力にサポートしてくれるとのこと。

インスコCursive: Getting Started にある通り、自分のIntelliJ IDEAのバージョンに合ったplugin.xmlプラグインリポジトリとして登録し、いつもの様にプラグイン検索してインストーすればOKです。

で、こちらが様子です。

https://i.gyazo.com/467d36e14326c7179f1b2aeb6cf3193f.png

テスト

なんか最初からテストやる環境も整ってるらしいです。いろいろ言うより見たほうが早いのでこちらどうぞ。

動画みたいな感じでテストが書けます。Clojure REPL(ローカルサーバ)を起動しておいて、カーソル位置にあるコード(テスト)をREPLサーバに送ってちくいち実行しています。

REPLへのコードの送るのは、コードの適当な位置を右クリックしてREPL→Run 'hoge' in REPLを選ぶか、「Enter action or option name」のダイアログだして「run repl」とかで検索すると出てくる「Run test under caret in REPL」を実行するかすると出来ます。

関数書く→テスト書く→カーソル位置のテストをREPLに送る→失敗する→関数実装する→カーソル位置のテストをREPLに送る→イカ繰り返し

なんかかっこいいですね(括弧だけに)。

FizzBuzz

さっきの画像でチラ見えしてますが、出来たコードがこちらです。

(ns cljtest.core)

(defn peek' [x]
  (do (println x) x))

(defn gen [n]
  (range 1 (+ n 1)))

(defn fizzbuzz [x]
  (if (= (mod x 15) 0)
    "FizzBuzz"
    (if (= (mod x 3) 0)
      "Fizz"
      (if (= (mod x 5) 0)
        "Buzz"
        x))))

(defn doFizzBuzz [n]
  (map (comp peek' fizzbuzz) (gen n)))

との事です。

追記

コメント欄であやぴーさんに指摘もらいましたので修正(もらった指摘はコメント欄見てください)。

(ns cljtest.core)

(defn peek' [x]
  (do (println x) x))

(defn gen [n]
  (range 1 (inc n)))

(defn fizzbuzz [x]
  (if (zero? (mod x 15))
    "FizzBuzz"
    (if (zero? (mod x 3))
      "Fizz"
      (if (zero? (mod x 5))
        "Buzz"
        x))))

(defn do-fizzBuzz [n]
  (doseq [x (gen n)]
    (peek' (fizzbuzz x))))

doseq、よく分からないんですけどリスト内包表記みたいなのとなんかしらの関数を引数にとって、関数を繰り返し実行するマクロ?っぽいです。副作用のある関数使う時に使うやつとのこと。

更に追記
(ns cljtest.core)

(defn gen [n]
  (range 1 (inc n)))

(defn fizzbuzz [x]
  (if (zero? (mod x 15))
    "FizzBuzz"
    (if (zero? (mod x 3))
      "Fizz"
      (if (zero? (mod x 5))
        "Buzz"
        x))))

(defn do-fizzbuzz [n]
  (doseq [x (gen n)]
    (println (fizzbuzz x))))

peek'関数いらないとのことです

まとめ

Clojure完全にマスターした