|
1 | | -clojure-style-guide |
2 | | -=================== |
| 1 | +# The Clojure Style Guide |
3 | 2 |
|
4 | | -A community coding style guide for the Clojure programming language |
| 3 | +This Clojure style guide recommends best practices so that real-world Clojure |
| 4 | +programmers can write code that can be maintained by other real-world Clojure |
| 5 | +programmers. A style guide that reflects real-world usage gets used, and a |
| 6 | +style guide that holds to an ideal that has been rejected by the people it is |
| 7 | +supposed to help risks not getting used at all – no matter how good it is. |
| 8 | + |
| 9 | +The guide is separated into several sections of related rules. I've |
| 10 | +tried to add the rationale behind the rules (if it's omitted I've |
| 11 | +assumed that is pretty obvious). |
| 12 | + |
| 13 | +I didn't come up with all the rules out of nowhere - they are mostly |
| 14 | +based on my extensive career as a professional software engineer, |
| 15 | +feedback and suggestions from members of the Clojure community and |
| 16 | +various highly regarded Clojure programming resources, such as |
| 17 | +["Clojure Programming"](http://www.clojurebook.com/) |
| 18 | +and ["The Joy of Clojure"](http://joyofclojure.com/). |
| 19 | + |
| 20 | +The guide is still a work in progress - some rules are lacking |
| 21 | +examples, some rules don't have examples that illustrate them clearly |
| 22 | +enough. In due time these issues will be addressed - just keep them in |
| 23 | +mind for now. |
| 24 | + |
| 25 | +You can generate a PDF or an HTML copy of this guide using |
| 26 | +[Transmuter](https://github.com/TechnoGate/transmuter). |
| 27 | + |
| 28 | +## Table of Contents |
| 29 | + |
| 30 | +* [Source Code Layout](#source-code-layout) |
| 31 | +* [Syntax](#syntax) |
| 32 | +* [Naming](#naming) |
| 33 | +* [Comments](#comments) |
| 34 | +* [Annotations](#annotations) |
| 35 | +* [Exceptions](#exceptions) |
| 36 | +* [Collections](#collections) |
| 37 | +* [Strings](#strings) |
| 38 | +* [Regular Expressions](#regular-expressions) |
| 39 | +* [Macros](#macros) |
| 40 | +* [Misc](#misc) |
| 41 | + |
| 42 | +## Source Code Layout |
| 43 | + |
| 44 | +> Nearly everybody is convinced that every style but their own is |
| 45 | +> ugly and unreadable. Leave out the "but their own" and they're |
| 46 | +> probably right... <br/> |
| 47 | +> -- Jerry Coffin (on indentation) |
| 48 | +
|
| 49 | +* Use two **spaces** per indentation level. No hard tabs. |
| 50 | + |
| 51 | + ```Clojure |
| 52 | + # good |
| 53 | + (when something |
| 54 | + (something-else)) |
| 55 | + |
| 56 | + # bad - four spaces |
| 57 | + (when something |
| 58 | + (something-else)) |
| 59 | + ``` |
| 60 | + |
| 61 | +* Use Unix-style line endings. (*BSD/Solaris/Linux/OSX users are covered by default, |
| 62 | + Windows users have to be extra careful.) |
| 63 | + * If you're using Git you might want to add the following |
| 64 | + configuration setting to protect your project from Windows line |
| 65 | + endings creeping in: |
| 66 | + |
| 67 | + $ git config --global core.autocrlf true |
| 68 | + |
| 69 | + |
| 70 | +* Use empty lines between `def`s. |
| 71 | + |
| 72 | + ```Clojure |
| 73 | + (def x ...) |
| 74 | + |
| 75 | + (def y ...) |
| 76 | + ``` |
| 77 | + |
| 78 | +* Keep lines up to 80 characters. |
| 79 | +* Avoid trailing whitespace. |
| 80 | + |
| 81 | +## Comments |
| 82 | + |
| 83 | +> Good code is its own best documentation. As you're about to add a |
| 84 | +> comment, ask yourself, "How can I improve the code so that this |
| 85 | +> comment isn't needed?" Improve the code and then document it to make |
| 86 | +> it even clearer. <br/> |
| 87 | +> -- Steve McConnell |
| 88 | + |
| 89 | +* Write self-documenting code and ignore the rest of this section. Seriously! |
| 90 | +* Comments longer than a word are capitalized and use punctuation. Use [one |
| 91 | + space](http://en.wikipedia.org/wiki/Sentence_spacing) after periods. |
| 92 | +* Avoid superfluous comments. |
| 93 | + |
| 94 | + ```Clojure |
| 95 | + # bad |
| 96 | + (inc counter) ; increments counter by one |
| 97 | + ``` |
| 98 | + |
| 99 | +* Keep existing comments up-to-date. An outdated is worse than no comment |
| 100 | +at all. |
| 101 | + |
| 102 | +> Good code is like a good joke - it needs no explanation. <br/> |
| 103 | +> -- Russ Olsen |
| 104 | + |
| 105 | +* Avoid writing comments to explain bad code. Refactor the code to |
| 106 | + make it self-explanatory. (Do or do not - there is no try. --Yoda) |
| 107 | + |
| 108 | +## Annotations |
| 109 | + |
| 110 | +* Annotations should usually be written on the line immediately above |
| 111 | + the relevant code. |
| 112 | +* The annotation keyword is followed by a colon and a space, then a note |
| 113 | + describing the problem. |
| 114 | +* If multiple lines are required to describe the problem, subsequent |
| 115 | + lines should be indented two spaces after the `;;`. |
| 116 | + |
| 117 | + ```Clojure |
| 118 | + (defn some-fun |
| 119 | + [] |
| 120 | + ;; FIXME: This has crashed occasionally since v1.2.3. It may |
| 121 | + ;; be related to the BarBazUtil upgrade. |
| 122 | + (baz)) |
| 123 | + ``` |
| 124 | + |
| 125 | +* In cases where the problem is so obvious that any documentation would |
| 126 | + be redundant, annotations may be left at the end of the offending line |
| 127 | + with no note. This usage should be the exception and not the rule. |
| 128 | + |
| 129 | + ```Clojure |
| 130 | + (defn bar |
| 131 | + [] |
| 132 | + (sleep 100)) ;; OPTIMIZE |
| 133 | + ``` |
| 134 | + |
| 135 | +* Use `TODO` to note missing features or functionality that should be |
| 136 | + added at a later date. |
| 137 | +* Use `FIXME` to note broken code that needs to be fixed. |
| 138 | +* Use `OPTIMIZE` to note slow or inefficient code that may cause |
| 139 | + performance problems. |
| 140 | +* Use `HACK` to note code smells where questionable coding practices |
| 141 | + were used and should be refactored away. |
| 142 | +* Use `REVIEW` to note anything that should be looked at to confirm it |
| 143 | + is working as intended. For example: `REVIEW: Are we sure this is how the |
| 144 | + client does X currently?` |
| 145 | +* Use other custom annotation keywords if it feels appropriate, but be |
| 146 | + sure to document them in your project's `README` or similar. |
| 147 | + |
| 148 | +## Misc |
| 149 | + |
| 150 | +* Avoid functions longer than 10 LOC (lines of code). Ideally, most |
| 151 | + functions will be shorter than 5 LOC. Empty lines do not contribute |
| 152 | + to the relevant LOC. |
| 153 | +* Avoid parameter lists longer than three or four parameters. |
| 154 | +* Code in a functional way, avoiding mutation when that makes sense. |
| 155 | +* Avoid more than three levels of block nesting. |
| 156 | +* Be consistent. In an ideal world, be consistent with these guidelines. |
| 157 | +* Use common sense. |
| 158 | + |
| 159 | +# Contributing |
| 160 | + |
| 161 | +Nothing written in this guide is set in stone. It's my desire to work |
| 162 | +together with everyone interested in Clojure coding style, so that we could |
| 163 | +ultimately create a resource that will be beneficial to the entire Clojure |
| 164 | +community. |
| 165 | + |
| 166 | +Feel free to open tickets or send pull requests with improvements. Thanks in |
| 167 | +advance for your help! |
| 168 | + |
| 169 | +# Spread the Word |
| 170 | + |
| 171 | +A community-driven style guide is of little use to a community that |
| 172 | +doesn't know about its existence. Tweet about the guide, share it with |
| 173 | +your friends and colleagues. Every comment, suggestion or opinion we |
| 174 | +get makes the guide just a little bit better. And we want to have the |
| 175 | +best possible guide, don't we? |
0 commit comments