Clojureスタイルガイド（日本語版）

Bozhidar Batsov氏によるClojureスタイルガイドを日本語訳しました。

**Clojureスタイルガイド https://totakke.github.io/clojure-style-guide/**

GitHubで管理されているコミュニティベースのコーディング規約集です。例も豊富でわかりやすいため、Clojurianは一度目を通しておくことをおすすめします。

本翻訳版もGitHubで管理されています。

**totakke/clojure-style-guide https://github.com/totakke/clojure-style-guide**

翻訳に関する指摘や修正は、IssueやPull Requestを作成してもらえれば、適宜修正を行っていきます。なお、スタイル自体への意見は原文プロジェクトにお願いします。

* 原文プロジェクト: [bbatsov/clojure-style-guide](https://github.com/bbatsov/clojure-style-guide)
* 原著作者: [Bozhidar Batsov](https://twitter.com/bbatsov)

----

以下にスタイルガイドの一部を紹介します。全文は [Clojureスタイルガイド](https://totakke.github.io/clojure-style-guide/) をご覧ください。

# サンプル

* 各インデントには **スペース** を使う。タブは使わない。<sup>[[リンク](https://github.com/totakke/clojure-style-guide#spaces)]</sup>

* `let`の束縛とマップのキーワードを揃える。<sup>[[リンク](https://github.com/totakke/clojure-style-guide#vertically-align-let-and-map)]</sup>

    ```clojure
    ;; 良い
    (let [thing1 "some stuff"
          thing2 "other stuff"]
      {:thing1 thing1
       :thing2 thing2})

    ;; 悪い
    (let [thing1 "some stuff"
      thing2 "other stuff"]
      {:thing1 thing1
      :thing2 thing2})
    ```

* 複数行にわたるドキュメント文字列はインデントする。<sup>[[リンク](https://github.com/totakke/clojure-style-guide#align-docstring-lines)]</sup>

    ```clojure
    ;; 良い
    (defn foo
      "Hello there. This is
      a multi-line docstring."
      []
      (bar))

    ;; 悪い
    (defn foo
      "Hello there. This is
    a multi-line docstring."
      []
      (bar))
    ```

* 1行が80文字を超えないようにする。<sup>[[リンク](https://github.com/totakke/clojure-style-guide#80-character-limits)]</sup>

* 行末の空白を避ける。<sup>[[リンク](https://github.com/totakke/clojure-style-guide#no-trailing-whitespace)]</sup>

* 名前空間ごとにファイルを分ける。<sup>[[リンク](https://github.com/totakke/clojure-style-guide#one-file-per-namespace)]</sup>

* 全ての名前空間は、複数の`refer`, `require`, `import`からなる`ns`フォームで始める。順序は慣習的に`refer`, `require`, `import`の順とする。<sup>[[リンク](https://github.com/totakke/clojure-style-guide#comprehensive-ns-declaration)]</sup>

    ```clojure
    (ns examples.ns
      (:refer-clojure :exclude [next replace remove])
      (:require [clojure.string :as s :refer [blank?]]
                [clojure.set :as set]
                [clojure.java.shell :as sh])
      (:import java.util.Date
               java.text.SimpleDateFormat
               [java.util.concurrent Executors
                                     LinkedBlockingQueue]))
    ```

* 関数本体内では、コンディションマップによる入力値、出力値のチェックがより良い。<sup>[[リンク](https://github.com/totakke/clojure-style-guide#pre-post-conditions)]</sup>

    ```clojure
    ;; 良い
    (defn foo [x]
      {:pre [(pos? x)]}
      (bar x))

    ;; 悪い
    (defn foo [x]
      (if (pos? x)
        (bar x)
        (throw (IllegalArgumentException "x must be a positive number!")))
    ```

* シーケンスが空かどうかをチェックするには`seq`を使う（このテクニックはしばしば *nil punning* と呼ばれる）。<sup>[[リンク](https://github.com/totakke/clojure-style-guide#nil-punning)]</sup>

    ```clojure
    ;; 良い
    (defn print-seq [s]
      (when (seq s)
        (prn (first s))
        (recur (rest s))))

    ;; 悪い
    (defn print-seq [s]
      (when-not (empty? s)
        (prn (first s))
        (recur (rest s))))
    ```

* `pred`や`coll`のような慣習名には`clojure.core`の例が参考になる。<sup>[[リンク](https://github.com/totakke/clojure-style-guide#idiomatic-names)]</sup>
    * 関数内では、
        * `f`, `g`, `h` - 関数入力
        * `n` - サイズを示す整数値
        * `index`, `i` - 整数のインデックス
        * `x`, `y` - 数値
        * `xs` - シーケンス
        * `m` - マップ
        * `s` - 文字列入力
        * `re` - 正規表現
        * `coll` - コレクション
        * `pred` - 述語クロージャ
        * `& more` - 可変長引数
        * `xf` - xform、transducer
    * マクロ内では、
        * `expr` - 式
        * `body` - マクロ本体
        * `binding` - マクロの束縛ベクタ

などなど。

詳しくは [Clojureスタイルガイド](https://totakke.github.io/clojure-style-guide/) へ。