├── CONTRIBUTING.md ├── README-koKO.md └── README.md /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | If you discover issues, have ideas for improvements, or 4 | want to contribute new rules, please report them to the 5 | [issue tracker][1] of the repository or submit a pull request. Please, 6 | try to follow these guidelines when you do so. 7 | 8 | ## Issue reporting 9 | 10 | * Check that the issue has not already been reported. 11 | * Be clear, concise and precise in your description of the problem. 12 | * Open an issue with a descriptive title and a summary in grammatically correct, 13 | complete sentences. 14 | * Include any relevant code to the issue summary. 15 | 16 | ## Pull requests 17 | 18 | * Read [how to properly contribute to open source projects on Github][2]. 19 | * Use a topic branch to easily amend a pull request later, if necessary. 20 | * Write [good commit messages][3]. 21 | * Use the same coding conventions as the rest of the project. 22 | * Open a [pull request][4] that relates to *only* one subject with a clear title 23 | and description in grammatically correct, complete sentences. 24 | 25 | [1]: https://github.com/bbatsov/clojure-style-guide/issues 26 | [2]: http://gun.io/blog/how-to-github-fork-branch-and-pull-request 27 | [3]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html 28 | [4]: https://help.github.com/articles/using-pull-requests 29 | -------------------------------------------------------------------------------- /README-koKO.md: -------------------------------------------------------------------------------- 1 | # The Clojure Style Guide 2 | 3 | > 롤 모델이 중요하다.
4 | > -- Officer Alex J. Murphy / RoboCop 5 | 6 | 이 클로저 스타일 가이드는 모범 사례를 추천하고 있기 때문에 7 | 실제 클로저 개발자들은 다른 클로저 개발자들과도 함께 유지보수가능한 코드를 작성할 수 있다. 8 | 9 | 여기 작성된 스타일 가이드는 실제 개발 환경에서 사용하고 있는 스타일을 기반으로 작성되었다. 10 | 또 잘 사용되지 않는 스타일(그게 아무리 좋다고 할지라도...)을 사용해서 생기는 문제를 개선하려는 사람들에 의해 정리된 내용을 담고있다. 11 | 12 | 가이드는 관련있는 규칙으로 묶은 여러개의 섹션으로 나뉘어져있다. 13 | 규칙을 적고나서는 합리적인 근거들을 덧붙이려 노력했다. 14 | (당연한 것이라고 가정한 것들은 생략하는 경우도 있다.) 15 | 16 | 모든 규칙은 갑자기 솟아난 것이 아니다; 17 | 이것들은 모두 소프트웨어 엔지니어로써의 광대한 내 경력, 18 | 클로저커뮤니티의 피드백과 제안, 풍부한 클로저 프로그래밍 리소스 (["Clojure Programming"](http://www.clojurebook.com/) 19 | 와 ["The Joy of Clojure"](http://joyofclojure.com/)) 이 뒷받침되어있다. 20 | 21 | 이 가이드는 계속 진행중이다; 22 | 몇 섹션은 없고, 어떤 섹션은 미완성이며, 몇개의 규칙들은 예가 부족하기도 하다. 23 | 몇개의 룰은 명확히 설명할 예가 없기도 하다. 24 | 언젠가 이런 이슈들은 해결될 것이다. — 일단 지금은 그렇다는 걸 알고 있으면 된다. 25 | 26 | 클로저 개발 커뮤니티에서 [라이브러리를 위한 코딩 표준](http://dev.clojure.org/display/community/Library+Coding+Standards) 27 | 목록을 정리하는 것도 주목해라. 28 | 29 | 이 가이드는 [Pandoc](http://pandoc.org/)를 통해 30 | PDF나 HTML로 복사해 갈 수 있다. 31 | 32 | 아래 언어로 번역된 가이드가 있다: 33 | 34 | * [일본어](https://github.com/totakke/clojure-style-guide/blob/ja/README.md) 35 | * [한글](https://github.com/kwakbab/clojure-style-guide/blob/master/README-koKO.md) 36 | 37 | ## Table of Contents 38 | 39 | * [소스코드 레이아웃 & 구조](#소스코드-레이아웃--구조) 40 | * [문법](#문법) 41 | * [네이밍](#네이밍) 42 | * [컬렉션](#컬렉션) 43 | * [뮤테이션](#뮤테이션) 44 | * [문자열](#문자열) 45 | * [예외](#예외) 46 | * [매크로](#매크로) 47 | * [주석](#주석) 48 | * [주석어노테이션](#주석어노테이션) 49 | * [문서화](#문서화) 50 | * [그밖에](#그밖에) 51 | * [도구들](#도구들) 52 | * [테스트](#테스트) 53 | 54 | ## 소스코드 레이아웃 & 구조 55 | 56 | > 거의 모든 사람들이 자신의 것을 제외한 모든 코딩 스타일이 번잡하고 가독성이 떨어진다고 확신한다. 57 | > 앞문장에서 "자신의 것을 제외한"을 없앤다면 아마도 맞는 말일지도...
58 | > -- Jerry Coffin (on indentation) 59 | 60 | * 61 | 탭은 들여쓰기 단위별로 **스페이스** 2칸을 사용하라. hard tab사용 안함 62 | [[link](#two-spaces)] 63 | 64 | ```Clojure 65 | ;; 좋은 예 66 | (when something 67 | (something-else)) 68 | 69 | ;; 나쁜 예 - 4칸 스페이스 70 | (when something 71 | (something-else)) 72 | ``` 73 | 74 | * 75 | 함수의 인수는 세로로 줄 맞춤 한다. 76 | [[link](#vertically-align-fn-args)] 77 | 78 | ```Clojure 79 | ;; 좋은 예 80 | (filter even? 81 | (range 1 10)) 82 | 83 | ;; 나쁜 예 84 | (filter even? 85 | (range 1 10)) 86 | ``` 87 | 88 | * 89 | let이 바인딩하는 것과 map키워드는 세로로 줄맞춤한다. 90 | [[link](#vertically-align-let-and-map)] 91 | 92 | ```Clojure 93 | ;; 좋은 예 94 | (let [thing1 "some stuff" 95 | thing2 "other stuff"] 96 | {:thing1 thing1 97 | :thing2 thing2}) 98 | 99 | ;; 나쁜 예 100 | (let [thing1 "some stuff" 101 | thing2 "other stuff"] 102 | {:thing1 thing1 103 | :thing2 thing2}) 104 | ``` 105 | 106 | * 107 | `defn`을 쓸때 docstring이 없을 때에는, 108 | 함수 이름과 인수 벡터를 한줄에 써도 좋고, 다음 줄에 나눠서 써도 좋다. 109 | [[link](#optional-new-line-after-fn-name)] 110 | 111 | ```Clojure 112 | ;; 좋은 예 113 | (defn foo 114 | [x] 115 | (bar x)) 116 | 117 | ;; 좋은 예 118 | (defn foo [x] 119 | (bar x)) 120 | 121 | ;; 나쁜 예 122 | (defn foo 123 | [x] (bar x)) 124 | ``` 125 | 126 | * 127 | 인수 벡터와 본체가 짧은 함수 사이의 개행은 생략할 수도 있다. 128 | [[link](#oneline-short-fn)] 129 | 130 | ```Clojure 131 | ;; 좋은 예 132 | (defn foo [x] 133 | (bar x)) 134 | 135 | ;; 짧은 본체를 가진 함수의 좋은 예 136 | (defn foo [x] (bar x)) 137 | 138 | ;; 다중 인수 함수의 좋은 예 139 | (defn foo 140 | ([x] (bar x)) 141 | ([x y] 142 | (if (predicate? x) 143 | (bar x) 144 | (baz x)))) 145 | 146 | ;; 나쁜 예 147 | (defn foo 148 | [x] (if (predicate? x) 149 | (bar x) 150 | (baz x))) 151 | ``` 152 | 153 | * 154 | 여러줄의 docstrings는 들여쓰기한다. 155 | [[link](#align-docstring-lines)] 156 | 157 | ```Clojure 158 | ;; 좋은 예 159 | (defn foo 160 | "Hello there. This is 161 | a multi-line docstring." 162 | [] 163 | (bar)) 164 | 165 | ;; 나쁜 예 166 | (defn foo 167 | "Hello there. This is 168 | a multi-line docstring." 169 | [] 170 | (bar)) 171 | ``` 172 | 173 | * * 174 | Unix 스타일로 줄바꿈 하라. 175 | (*BSD/Solaris/Linux/OS X 사용자들은 기본으로 설정되어 있다. Windows 사용자에겐 특히 주의가 필요하다.) 176 | [[link](#crlf)] 177 | 178 | * 만약 Git을 사용하고 있으면, 다음 설정을 추가함으로써 프로젝트가 179 | Windows 줄바꿈 형식으로 강제 설정되는 것을 막을 수 있을 것이다.: 180 | 181 | ``` 182 | bash$ git config --global core.autocrlf true 183 | ``` 184 | 185 | * 186 | 괄호로 시작되거나(`(`, `{`,`[`), 괄호로 끝나는 (`)`, `}` , `]`) 텍스트가 있으면 187 | 다른 텍스트와 공백으로 분리해라. 188 | 반대로, 괄호 바로 뒤와 바로 앞은 괄호와 텍스트 사이에 공백을 남기지 마라 . 189 | [[link](#bracket-spacing)] 190 | 191 | ```Clojure 192 | ;; 좋은 예 193 | (foo (bar baz) quux) 194 | 195 | ;; 나쁜 예 196 | (foo(bar baz)quux) 197 | (foo ( bar baz ) quux) 198 | ``` 199 | 200 | > 사람이 이해하기 쉬운 언어 문법은 세미콜론 암을 유발한다.
201 | > -- Alan Perlis 202 | 203 | * 204 | 순서가 있는 콜렉션 리터럴의 엘리먼트 사이에 콤마를 사용하지 마라. 205 | [[link](#no-commas-for-seq-literals)] 206 | 207 | ```Clojure 208 | ;; 좋은 예 209 | [1 2 3] 210 | (1 2 3) 211 | 212 | ;; 나쁜 예 213 | [1, 2, 3] 214 | (1, 2, 3) 215 | ``` 216 | 217 | * 218 | 맵 리터럴 사용시 적절한 줄바꿈이나 콤마를 통해 가독성을 높이는데에 신경써라. 219 | [[link](#opt-commas-in-map-literals)] 220 | 221 | ```Clojure 222 | ;; 좋은 예 223 | {:name "Bruce Wayne" :alter-ego "Batman"} 224 | 225 | ;; 좋은 예, 확실히 더 읽기 좋다. 226 | {:name "Bruce Wayne" 227 | :alter-ego "Batman"} 228 | 229 | ;; 좋은 예, 좀 더 간결하다. 230 | {:name "Bruce Wayne", :alter-ego "Batman"} 231 | ``` 232 | 233 | * 234 | 마지막에 따라오는 괄호들은 따로 다른 줄에 놓지 않고 한 줄에 함께 써라. 235 | [[link](#gather-trailing-parens)] 236 | 237 | ```Clojure 238 | ;; 좋은 예; 한 줄 239 | (when something 240 | (something-else)) 241 | 242 | ;; 나쁜 예; 구분된 줄 243 | (when something 244 | (something-else) 245 | ) 246 | ``` 247 | 248 | * 249 | 최상위의 구문들 사이에는 빈 줄을 넣어라. 250 | [[link](#empty-lines-between-top-level-forms)] 251 | 252 | ```Clojure 253 | ;; 좋은 예 254 | (def x ...) 255 | 256 | (defn foo ...) 257 | 258 | ;; 나쁜 예 259 | (def x ...) 260 | (defn foo ...) 261 | ``` 262 | 263 | 관련있는 `def`들을 붙여쓰는 것은 예외다. 264 | 265 | ```Clojure 266 | ;; 좋은 예 267 | (def min-rows 10) 268 | (def max-rows 20) 269 | (def min-cols 15) 270 | (def max-cols 30) 271 | ``` 272 | 273 | * 274 | 함수나 매크로 정의 중간에 빈 줄을 넣지 마라. 275 | 짝을 이루는 구조를 표현할 때는 예외다. (예: `let`,`cond` 사용시) 276 | [[link](#no-blank-lines-within-def-forms)] 277 | 278 | * 279 | 가능하면, 한 줄이 80글자 이상되는 것은 피해라. 280 | [[link](#80-character-limits)] 281 | 282 | * 283 | 맨뒤의 공백은 피해라. 284 | [[link](#no-trailing-whitespace)] 285 | 286 | * 287 | 한 개의 네임스페이스에는 한 개의 파일을 사용해라. 288 | [[link](#one-file-per-namespace)] 289 | 290 | * 291 | 모든 네임스페이스는 포괄적인 의미가 있는 `ns`구문으로 시작해라. 292 | `ns`는 `import`,`require`,`refer`,`use` 등으로 구성된다. 293 | [[link](#comprehensive-ns-declaration)] 294 | 295 | ```Clojure 296 | (ns examples.ns 297 | (:refer-clojure :exclude [next replace remove]) 298 | (:require [clojure.string :as s :refer [blank?]] 299 | [clojure.set :as set] 300 | [clojure.java.shell :as sh]) 301 | (:use [clojure xml zip]) 302 | (:import java.util.Date 303 | java.text.SimpleDateFormat 304 | [java.util.concurrent Executors 305 | LinkedBlockingQueue])) 306 | ``` 307 | 308 | * 309 | ns 매크로 사용시 `:use`보다 `:require :refer :all`사용을 권장한다. 310 | [[link](#prefer-require-over-use)] 311 | 312 | ```Clojure 313 | ;; 좋은 예 314 | (ns examples.ns 315 | (:require [clojure.zip :refer :all])) 316 | 317 | ;; 나쁜 예 318 | (ns examples.ns 319 | (:use clojure.zip)) 320 | ``` 321 | 322 | * 323 | 하나로 구분된 네임스페이스는 피해라. 324 | [[link](#no-single-segment-namespaces)] 325 | 326 | ```Clojure 327 | ;; 좋은 예 328 | (ns example.ns) 329 | 330 | ;; 나쁜 예 331 | (ns example) 332 | ``` 333 | 334 | * 335 | 너무 긴 네임스페이스는 피해라 (예: 5개 이상으로 이루어진 네임스페이스는 피해라.) 336 | [[link](#namespaces-with-5-segments-max)] 337 | 338 | * 339 | 10줄이 넘는 함수는 피해라. 340 | 이상적으로 모든 함수는 5줄보다 적어야한다. 341 | [[link](#10-loc-per-fn-limit)] 342 | 343 | * 344 | 3개이상의 파라미터와 함께 쓰는 리스트나 4개 연속의 파라미터는 피하라. 345 | [[link](#4-positional-fn-params-limit)] 346 | 347 | ## 문법 348 | 349 | * 350 | `require`, `refer`와 같이 네임스페이스를 처리하는 함수의 사용을 피하자. 351 | REPL 환경 밖에서 전혀 필요하지 않다. 352 | [[link](#ns-fns-only-in-repl)] 353 | 354 | * 355 | 이 후의 참조에 대해서 `declare`을 사용하자. 356 | [[link](#declare)] 357 | 358 | * 359 | `loop/recur`보다 `map`과 같은 고차함수를 사용하자. 360 | [[link](#higher-order-fns)] 361 | 362 | * 363 | 함수 내부에 확인할 조건이 있을 때 pre와 post 함수를 사용하자. 364 | [[link](#pre-post-conditions)] 365 | 366 | ```Clojure 367 | ;; 좋은 예 368 | (defn foo [x] 369 | {:pre [(pos? x)]} 370 | (bar x)) 371 | 372 | ;; 나쁜 예 373 | (defn foo [x] 374 | (if (pos? x) 375 | (bar x) 376 | (throw (IllegalArgumentException "x must be a positive number!"))) 377 | ``` 378 | 379 | * 380 | 함수 안에 var를 선언하지 말자. 381 | [[link](#dont-def-vars-inside-fns)] 382 | 383 | ```Clojure 384 | ;; 매우 나쁜 예 385 | (defn foo [] 386 | (def x 5) 387 | ...) 388 | ``` 389 | 390 | * 391 | 내부 바인딩으로 `clojure.core`의 이름을 사용하지 말자. 392 | [[link](#dont-shadow-clojure-core)] 393 | 394 | ```Clojure 395 | ;; 나쁜 예 - 내부에 clojure.core/map 사용을 강제한다. 396 | (defn foo [map] 397 | ...) 398 | ``` 399 | 400 | * 401 | 시퀀스가 비어있을 때 종료하는 조건에는 `seq`를 사용하자. (이 기술은 종종 *nil punning*이라 불린다.) 402 | [[link](#nil-punning)] 403 | 404 | ```Clojure 405 | ;; 좋은 예 406 | (defn print-seq [s] 407 | (when (seq s) 408 | (prn (first s)) 409 | (recur (rest s)))) 410 | 411 | ;; 나쁜 예 412 | (defn print-seq [s] 413 | (when-not (empty? s) 414 | (prn (first s)) 415 | (recur (rest s)))) 416 | ``` 417 | 418 | * 419 | `(if ... (do ...)` 대신 `when`을 사용하자. 420 | [[link](#when-instead-of-single-branch-if)] 421 | 422 | ```Clojure 423 | ;; 좋은 예 424 | (when pred 425 | (foo) 426 | (bar)) 427 | 428 | ;; 나쁜 예 429 | (if pred 430 | (do 431 | (foo) 432 | (bar))) 433 | ``` 434 | 435 | * 436 | `let` + `if` 대신 `if-let`을 사용하자. 437 | [[link](#if-let)] 438 | 439 | ```Clojure 440 | ;; 좋은 예 441 | (if-let [result (foo x)] 442 | (something-with result) 443 | (something-else)) 444 | 445 | ;; 나쁜 예 446 | (let [result (foo x)] 447 | (if result 448 | (something-with result) 449 | (something-else))) 450 | ``` 451 | 452 | * 453 | `let` + `when` 대신 `when-let`을 사용하자. 454 | [[link](#when-let)] 455 | 456 | ```Clojure 457 | ;; 좋은 예 458 | (when-let [result (foo x)] 459 | (do-something-with result) 460 | (do-something-more-with result)) 461 | 462 | ;; 나쁜 예 463 | (let [result (foo x)] 464 | (when result 465 | (do-something-with result) 466 | (do-something-more-with result))) 467 | ``` 468 | 469 | * 470 | `(if (not ...) ...)` 대신 `if-not`을 사용하자.. 471 | [[link](#if-not)] 472 | 473 | ```Clojure 474 | ;; 좋은 예 475 | (if-not (pred) 476 | (foo)) 477 | 478 | ;; 나쁜 예 479 | (if (not pred) 480 | (foo)) 481 | ``` 482 | 483 | * 484 | `(when (not ...) ...)` 대신 `when-not`을 사용하자. 485 | [[link](#when-not)] 486 | 487 | ```Clojure 488 | ;; 좋은 예 489 | (when-not pred 490 | (foo) 491 | (bar)) 492 | 493 | ;; 나쁜 예 494 | (when (not pred) 495 | (foo) 496 | (bar)) 497 | ``` 498 | 499 | * 500 | `(if-not ... (do ...)` 대신 `when-not`을 사용하자. 501 | [[link](#when-not-instead-of-single-branch-if-not)] 502 | 503 | ```Clojure 504 | ;; 좋은 예 505 | (when-not pred 506 | (foo) 507 | (bar)) 508 | 509 | ;; 나쁜 예 510 | (if-not pred 511 | (do 512 | (foo) 513 | (bar))) 514 | ``` 515 | 516 | * 517 | `(not (= ...))` 대신 `not=`을 사용하자. 518 | [[link](#not-equal)] 519 | 520 | ```Clojure 521 | ;; 좋은 예 522 | (not= foo bar) 523 | 524 | ;; 나쁜 예 525 | (not (= foo bar)) 526 | ``` 527 | 528 | * 529 | 비교할 때, 클로저의 `<`, `>`, 기타 함수 들은 여러 개의 인수를 받을 수 있다는 점을 명심하자. 530 | [[link](#multiple-arity-of-gt-and-ls-fns)] 531 | 532 | ```Clojure 533 | ;; 좋은 예 534 | (< 5 x 10) 535 | 536 | ;; 나쁜 예 537 | (and (> x 5) (< x 10)) 538 | ``` 539 | 540 | * 541 | 함수 리터럴 안에서 하나의 파라미터를 받는 경우에는 `%1` 보다 `%`를 사용하자. 542 | [[link](#single-param-fn-literal)] 543 | 544 | ```Clojure 545 | ;; 좋은 예 546 | #(Math/round %) 547 | 548 | ;; 나쁜 예 549 | #(Math/round %1) 550 | ``` 551 | 552 | * 553 | 함수 리터럴 안에서 여러 개의 파라미터를 받는 경우에는 `%` 보다 `%1`를 사용하자. 554 | [[link](#multiple-params-fn-literal)] 555 | 556 | ```Clojure 557 | ;; 좋은 예 558 | #(Math/pow %1 %2) 559 | 560 | ;; 나쁜 예 561 | #(Math/pow % %2) 562 | ``` 563 | 564 | * 565 | 불필요하게 익명함수로 감싸지 말자. 566 | [[link](#no-useless-anonymous-fns)] 567 | 568 | ```Clojure 569 | ;; 좋은 예 570 | (filter even? (range 1 10)) 571 | 572 | ;; 나쁜 예 573 | (filter #(even? %) (range 1 10)) 574 | ``` 575 | 576 | * 577 | 함수 바디가 여러개의 구문으로 구성되는 경우 함수 리터럴을 사용하지 말자. 578 | [[link](#no-multiple-forms-fn-literals)] 579 | 580 | ```Clojure 581 | ;; 좋은 예 582 | (fn [x] 583 | (println x) 584 | (* x 2)) 585 | 586 | ;; 나쁜 예 ( 명시적으로 do 구문이 필요하다.) 587 | #(do (println %) 588 | (* % 2)) 589 | ``` 590 | 591 | * 592 | 익명함수의 사용보다 `complement` 함수를 사용하자. 593 | [[link](#complement)] 594 | 595 | ```Clojure 596 | ;; 좋은 예 597 | (filter (complement some-pred?) coll) 598 | 599 | ;; 나쁜 예 600 | (filter #(not (some-pred? %)) coll) 601 | ``` 602 | 603 | 분리함수의 폼 안에 여집합 속성이 있는 경우 이 규칙은 무시하자 (e.g. `even?` and `odd?`). 604 | 605 | * 606 | 코드가 더 간단해 질 수 있다면 `comp`를 활용한다. 607 | [[link](#comp)] 608 | 609 | ```Clojure 610 | ;; `(:require [clojure.string :as str])`이 되었다고 가정... 611 | 612 | ;; 좋은 예 613 | (map #(str/capitalize (str/trim %)) ["top " " test "]) 614 | 615 | ;; 더 좋은 예 616 | (map (comp str/capitalize str/trim) ["top " " test "]) 617 | ``` 618 | 619 | * 620 | 코드가 더 간단해 질 수 있다면 `partial`을 활용한다. 621 | [[link](#partial)] 622 | 623 | ```Clojure 624 | ;; 좋은 예 625 | (map #(+ 5 %) (range 1 10)) 626 | 627 | ;; (틀림없이) 좋은 예 628 | (map (partial + 5) (range 1 10)) 629 | ``` 630 | 631 | * 632 | 구문이 지나치게 중첩되어 있을 때는 쓰레딩 매크로를 권장한다. 633 | (`->` (thread-first) 와 `->>`(thread-last)) 634 | [[link](#threading-macros)] 635 | 636 | ```Clojure 637 | ;; 좋은 예 638 | (-> [1 2 3] 639 | reverse 640 | (conj 4) 641 | prn) 642 | 643 | ;; 좋지 않은 예 644 | (prn (conj (reverse [1 2 3]) 645 | 4)) 646 | 647 | ;; 좋은 예 648 | (->> (range 1 10) 649 | (filter even?) 650 | (map (partial * 2))) 651 | 652 | ;; 좋지 않은 예 653 | (map (partial * 2) 654 | (filter even? (range 1 10))) 655 | ``` 656 | 657 | * 658 | `cond`에서 모든 경우의 조건표현식을 처리할 때는 `:else` 키워드를 쓴다. 659 | [[link](#else-keyword-in-cond)] 660 | 661 | ```Clojure 662 | ;; 좋은 예 663 | (cond 664 | (neg? n) "negative" 665 | (pos? n) "positive" 666 | :else "zero")) 667 | 668 | ;; 나쁜 예 669 | (cond 670 | (neg? 0) "negative" 671 | (pos? 0) "positive" 672 | true "zero")) 673 | ``` 674 | 675 | * 676 | 비교하려는 값과 조건이 바뀌지 않을 때는 `cond`보다 `condp`를 써라. 677 | [[link](#condp)] 678 | 679 | ```Clojure 680 | ;; 좋은 예 681 | (cond 682 | (= x 10) :ten 683 | (= x 20) :twenty 684 | (= x 30) :thirty 685 | :else :dunno) 686 | 687 | ;; 훨씬 좋은 예 688 | (condp = x 689 | 10 :ten 690 | 20 :twenty 691 | 30 :thirty 692 | :dunno) 693 | ``` 694 | 695 | * 696 | 조건표현식이 상수일 때 `cond`나 `condp`보다 `case`를 권장한다. 697 | [[link](#case)] 698 | 699 | ```Clojure 700 | ;; 좋은 예 701 | (cond 702 | (= x 10) :ten 703 | (= x 20) :twenty 704 | (= x 30) :forty 705 | :else :dunno) 706 | 707 | ;; 더 좋은 예 708 | (condp = x 709 | 10 :ten 710 | 20 :twenty 711 | 30 :forty 712 | :dunno) 713 | 714 | ;; 가장 좋은 예 715 | (case x 716 | 10 :ten 717 | 20 :twenty 718 | 30 :forty 719 | :dunno) 720 | ``` 721 | 722 | * 723 | `cond`와 관련된 곳에서 짧은 폼을 써라. 불가능하다면 주석이나 빈 줄 등으로 쌍이 잘 구분되도록 힌트를 주자. 724 | [[link](#shor-forms-in-cond)] 725 | 726 | ```Clojure 727 | ;; 좋은 예 728 | (cond 729 | (test1) (action1) 730 | (test2) (action2) 731 | :else (default-action)) 732 | 733 | ;; 괜찮은 예 734 | (cond 735 | ;; test case 1 736 | (test1) 737 | (long-function-name-which-requires-a-new-line 738 | (complicated-sub-form 739 | (-> 'which-spans 740 | multiple-lines))) 741 | 742 | (test2) 743 | (another-very-long-function-name 744 | (yet-another-sub-form 745 | (-> 'which-spans 746 | multiple-lines))) 747 | 748 | :else 749 | (the-fall-through-default-case 750 | (which-also-spans 'multiple 751 | 'lines))) 752 | ``` 753 | 754 | * 755 | 참이나 거짓을 판단하는 구문 대신에, `set` 사용할 수 있다면 그렇게 하라. 756 | [[link](#set-as-predicate)] 757 | 758 | ```Clojure 759 | ;; 좋은 예 760 | (remove #{0} [0 1 2 3 4 5]) 761 | 762 | ;; 나쁜 예 763 | (remove #(= % 0) [0 1 2 3 4 5]) 764 | 765 | ;; 좋은 예 766 | (count (filter #{\a \e \i \o \u} "mary had a little lamb")) 767 | 768 | ;; 나쁜 예 769 | (count (filter #(or (= % \a) 770 | (= % \e) 771 | (= % \i) 772 | (= % \o) 773 | (= % \u)) 774 | "mary had a little lamb")) 775 | ``` 776 | 777 | * 778 | `(+ x 1)` and `(- x 1)` 대신 `(inc x)` & `(dec x)`를 사용한다. 779 | [[link](#inc-and-dec)] 780 | 781 | * 782 | `(> x 0)`, `(< x 0)` & `(= x 0)` 대신 `(pos? x)`, `(neg? x)` & `(zero? x)`를 사용한다. 783 | [[link](#pos-and-neg)] 784 | 785 | * 786 | 중첩된 `cons` 대신 `list*`를 사용한다. 787 | [[link](#list-star-instead-of-nested-cons)] 788 | 789 | ```Clojure 790 | ;; 좋은 예 791 | (list* 1 2 3 [4 5]) 792 | 793 | ;;나쁜 예 794 | (cons 1 (cons 2 (cons 3 [4 5]))) 795 | 796 | ``` 797 | 798 | * 799 | 자바를 사용할 때는 줄인 문법을 사용한다. 800 | [[link](#sugared-java-interop)] 801 | 802 | ```Clojure 803 | ;;; 객체 생성 804 | ;; 좋은 예 805 | (java.util.ArrayList. 100) 806 | 807 | ;; 나쁜 예 808 | (new java.util.ArrayList 100) 809 | 810 | ;;; 정적 메서드 사용 811 | ;; 좋은 예 812 | (Math/pow 2 10) 813 | 814 | ;; 나쁜 예 815 | (. Math pow 2 10) 816 | 817 | ;;; 인스턴스 메서드 사용 818 | ;; 좋은 예 819 | (.substring "hello" 1 3) 820 | 821 | ;; 나쁜 예 822 | (. "hello" substring 1 3) 823 | 824 | ;;; 정적 필드 사용 825 | ;; 좋은 예 826 | Integer/MAX_VALUE 827 | 828 | ;; 나쁜 예 829 | (. Integer MAX_VALUE) 830 | 831 | ;;; 인스턴스 필드 사용 832 | ;; 좋은 예 833 | (.someField some-object) 834 | 835 | ;; 나쁜 예 836 | (. some-object someField) 837 | ``` 838 | 839 | * 840 | 키워드와 true 값을 가지는 메타데이터는 리더매크로를 사용해서 짧게 줄여 쓴다. 841 | [[link](#compact-metadata-notation-for-true-flags)] 842 | 843 | ```Clojure 844 | ;; 좋은 예 845 | (def ^:private a 5) 846 | 847 | ;; 나쁜 예 848 | (def ^{:private true} a 5) 849 | ``` 850 | 851 | * 852 | 비공개 코드는 표시를 해라. 853 | [[link](#private)] 854 | 855 | ```Clojure 856 | ;; 좋은 예 857 | (defn- private-fun [] ...) 858 | 859 | (def ^:private private-var ...) 860 | 861 | ;; 나쁜 예 862 | (defn private-fun [] ...) ; 비공개가 아님 863 | 864 | (defn ^:private private-fun [] ...) ; 장황하다. 865 | 866 | (def private-var ...) ; 비공개가 아님 867 | ``` 868 | 869 | * 870 | 메타데이터를 붙일 때는 어디에 붙일지 주의해서 사용해라. 871 | [[link](#attach-metadata-carefully)] 872 | 873 | ```Clojure 874 | ;; `a`의 var 참조에 메타데이터를 붙인다. 875 | (def ^:private a {}) 876 | (meta a) ;=> nil 877 | (meta #'a) ;=> {:private true} 878 | 879 | ;; 빈 해시값에 메타데이터를 붙인다. 880 | (def a ^:private {}) 881 | (meta a) ;=> {:private true} 882 | (meta #'a) ;=> nil 883 | ``` 884 | 885 | ## 네이밍 886 | 887 | > 프로그래밍에서 가장 어려운 것은 캐시 무효화하는 것과 네이밍이다.
888 | > -- Phil Karlton 889 | 890 | * 891 | 네임스페이스에 대한 네이밍은 다음 두가지 방법 중 하나를 사용하는 것이 좋다: 892 | [[link](#ns-naming-schemas)] 893 | 894 | * `project.module` 895 | * `organization.project.module` 896 | 897 | * 898 | 네임스페이스의 단어 구분은 `lisp-case`를 사용한다.(예 `bruce.project-euler`) 899 | [[link](#lisp-case-ns)] 900 | 901 | * 902 | 함수와 변수는 `lisp-case`를 사용한다. 903 | [[link](#lisp-case)] 904 | 905 | ```Clojure 906 | ;; 좋은 예 907 | (def some-var ...) 908 | (defn some-fun ...) 909 | 910 | ;; 나쁜 예 911 | (def someVar ...) 912 | (defn somefun ...) 913 | (def some_fun ...) 914 | ``` 915 | 916 | * 917 | 프로토콜, 레코드, 구조체, 타입에는 `CamelCase`를 사용한다. (HTTP, RFC, XML과 같은 약자는 918 | 대문자를 사용한다.) 919 | [[link](#CamelCase-for-protocols-records-structs-and-types)] 920 | 921 | * 922 | 참이나 거짓을 리턴하는 함수의 이름 끝에는 물음표를 붙인다. 923 | (예., `even?`). 924 | [[link](#pred-with-question-mark)] 925 | 926 | ```Clojure 927 | ;; 좋은 예 928 | (defn palindrome? ...) 929 | 930 | ;; 나쁜 예 931 | (defn palindrome-p ...) ; Common Lisp 스타일 932 | (defn is-palindrome ...) ; 자바 스타일 933 | ``` 934 | 935 | * 936 | STM 트랜젝션에 안전하지 않은 함수나 매크로 이름 뒤에는 느낌표를 붙인다. (예. `reset!`). 937 | [[link](#changing-state-fns-with-exclamation-mark)] 938 | 939 | * 940 | 변환 함수 이름에 있는 `to` 대신 `->`를 사용한다. 941 | [[link](#arrow-instead-of-to)] 942 | 943 | ```Clojure 944 | ;; 좋은 예 945 | (defn f->c ...) 946 | 947 | ;; 좋지 않음 948 | (defn f-to-c ...) 949 | ``` 950 | 951 | * 952 | 바인딩이 여러번 될 수 있을 때는 (즉, 다이나믹인 경우), 이름 양쪽에 `*`표시를 해준다. 953 | [[link](#earmuffs-for-dynamic-vars)] 954 | 955 | ```Clojure 956 | ;; 좋은 예 957 | (def ^:dynamic *a* 10) 958 | 959 | ;; 나쁜 예 960 | (def ^:dynamic a 10) 961 | ``` 962 | 963 | * 964 | 상수 값은 특별한 표시를 하지 않는다; 특별한 표시가 없으면 모든 것이 상수라고 가정한다. 965 | [[link](#dont-flag-constants)] 966 | 967 | * 968 | 사용하지 않는 인수 이름은 `_`로 디스트럭처링을 해준다. 969 | [[link](#underscore-for-unused-bindings)] 970 | 971 | ```Clojure 972 | ;; 좋은 예 973 | (let [[a b _ c] [1 2 3 4]] 974 | (println a b c)) 975 | 976 | (dotimes [_ 3] 977 | (println "Hello!")) 978 | 979 | ;; 나쁜 예 980 | (let [[a b c d] [1 2 3 4]] 981 | (println a b d)) 982 | 983 | (dotimes [i 3] 984 | (println "Hello!")) 985 | ``` 986 | 987 | * 988 | `pred`와 `coll`과 같은 `clojure.core`에서 사용된 관용어를 사용한다. 989 | [[link](#idiomatic-names)] 990 | 991 | * 함수 안에서: 992 | * `f`, `g`, `h` - 함수 값 993 | * `n` - 크기 같은 숫자 값 994 | * `index` - 숫자 인덱스 995 | * `x`, `y` - 숫자 996 | * `xs` - 시퀀스 997 | * `m` - 맵 998 | * `s` - 문자열 입력 999 | * `re` - 정규식 표현 1000 | * `coll` - 컬렉션 1001 | * `pred` - 참이나 거짓을 리턴하는 함수 1002 | * `& more` - 가변 인자 1003 | * `xf` - 트랜스듀서에 xform 1004 | * in macros: 1005 | * `expr` - 표현식 1006 | * `body` - 바디 1007 | * `binding` - 매크로 바인딩 벡터 1008 | 1009 | ## 컬렉션 1010 | 1011 | > 10개의 데이터 구조를 10개의 함수로 조작하는 것 보다 1012 | > 1개의 데이터 구조를 100개의 함수로 조작하는 것이 낫다.
1013 | > -- Alan J. Perlis (최초의 튜링상 수상자) 1014 | 1015 | * 1016 | 꼭 필요한 경우를 제외하고 제너릭(특정 타입을 가지는) 데이터를 가지는 리스트는 사용하지 않는다. 1017 | [[link](#avoid-lists)] 1018 | 1019 | * 1020 | 해시 키는 키워드를 권장한다. 1021 | [[link](#keywords-for-hash-keys)] 1022 | 1023 | ```Clojure 1024 | ;; 좋은 예 1025 | {:name "Bruce" :age 30} 1026 | 1027 | ;; 나쁜 예 1028 | {"name" "Bruce" "age" 30} 1029 | ``` 1030 | 1031 | * 1032 | 가능하면 리터럴 컬렉션 문법을 권장한다. 다만 set을 정의할 때는 컴파일 타임에 1033 | 값이 정해져 있는 경우에만 리터럴 문법을 사용한다. 1034 | [[link](#literal-col-syntax)] 1035 | 1036 | ```Clojure 1037 | ;; 좋은 예 1038 | [1 2 3] 1039 | #{1 2 3} 1040 | (hash-set (func1) (func2)) ; 런타임에 값이 결정된다. 1041 | 1042 | ;; 나쁜 예 1043 | (vector 1 2 3) 1044 | (hash-set 1 2 3) 1045 | #{(func1) (func2)} ; (func1)와 (func2)의 값이 같다면 예외가 발생한다. 1046 | ``` 1047 | 1048 | * 1049 | 가능하면 인덱스를 사용하여 컬렉션에 접근하는 것을 피한다. 1050 | [[link](#avoid-index-based-coll-access)] 1051 | 1052 | * 1053 | 가능하면 맵에서 값을 가져올 때 키워드를 함수처럼 사용하는 것을 권장한다. 1054 | [[link](#keywords-as-fn-to-get-map-values)] 1055 | 1056 | ```Clojure 1057 | (def m {:name "Bruce" :age 30}) 1058 | 1059 | ;; 좋은 예 1060 | (:name m) 1061 | 1062 | ;; 필요 이상으로 많은 단어를 사용한다. 1063 | (get m :name) 1064 | 1065 | ;; 나쁜 예 - NullPointerException이 발생 할 가능성이 있다. 1066 | (m :name) 1067 | ``` 1068 | 1069 | * 1070 | 컬렉션은 컬렉션의 항목을 가져오는 함수라는 사실을 잊지 말자. 1071 | [[link](#colls-as-fns)] 1072 | 1073 | ```Clojure 1074 | ;; 좋은 예 1075 | (filter #{\a \e \o \i \u} "this is a test") 1076 | 1077 | ;; 나쁜 예 - 공유하기에는 너무 구리다. 1078 | ``` 1079 | 1080 | * 1081 | 키워드는 함수로 사용할 수 있다는 사실을 잊지 말자. 1082 | [[link](#keywords-as-fns)] 1083 | 1084 | ```Clojure 1085 | ((juxt :a :b) {:a "ala" :b "bala"}) 1086 | ``` 1087 | 1088 | * 1089 | 성능상의 이유가 아니면 transient 컬렉션 사용을 피한다. 1090 | [[link](#avoid-transient-colls)] 1091 | 1092 | * 1093 | 자바 컬렉션 사용을 피한다. 1094 | [[link](#avoid-java-colls)] 1095 | 1096 | * 1097 | 자바 배열 사용을 피한다. 단 자바와 상호작용이 필요하거나 기본 타입을 많이 다뤄서 성능에 영향을 주는 1098 | 경우는 제외한다. 1099 | [[link](#avoid-java-arrays)] 1100 | 1101 | ## 뮤테이션 1102 | 1103 | ### 레퍼런스 1104 | 1105 | * 1106 | 트랜젝션 안에서 뜻하지 않는 반복 실행을 피하기 위해서 모든 I/O 호출에 `io!` 매크로를 사용해서 감싸는 1107 | 것을 검토한다. 1108 | [[link](#refs-io-macro)] 1109 | 1110 | * 1111 | 가능하면 `ref-set` 사용을 피한다. 1112 | [[link](#refs-avoid-ref-set)] 1113 | 1114 | ```Clojure 1115 | (def r (ref 0)) 1116 | 1117 | ;; 좋은 예 1118 | (dosync (alter r + 5)) 1119 | 1120 | ;; 나쁜 예 1121 | (dosync (ref-set r 5)) 1122 | ``` 1123 | 1124 | * 1125 | 트랜젝션의 크기(안에 있는 기능의 수)는 작으면 작을 수록 좋다. 1126 | [[link](#refs-small-transactions)] 1127 | 1128 | * 1129 | 같은 레퍼러스를 사용하는 긴 트랜젝션과 짧은 트랜젝션을 함께 사용하는 것을 피한다. 1130 | [[link](#refs-avoid-short-long-transactions-with-same-ref)] 1131 | 1132 | ### 에이전트 1133 | 1134 | * 1135 | CPU bound와 블럭되지 않는 I/O, 다른 쓰레드에만 `send`를 사용한다. 1136 | [[link](#agents-send)] 1137 | 1138 | * 1139 | 블럭이 될지 모르거나 Sleep되거나 스레드가 오랫동안 작업할 것 같은 곳에는 `send-off`를 사용한다. 1140 | [[link](#agents-send-off)] 1141 | 1142 | ### 애텀 1143 | 1144 | * 1145 | STM 트랜젝션 안에서 애텀이 변경 되는 것을 피한다. 1146 | [[link](#atoms-no-update-within-transactions)] 1147 | 1148 | * 1149 | 가능하면 `reset!`보다 `swap!`을 사용한다. 1150 | [[link](#atoms-prefer-swap-over-reset)] 1151 | 1152 | ```Clojure 1153 | (def a (atom 0)) 1154 | 1155 | ;; 좋은 예 1156 | (swap! a + 5) 1157 | 1158 | ;; 그리 좋지 않음 1159 | (reset! a 5) 1160 | ``` 1161 | 1162 | ## 문자열 1163 | 1164 | * 1165 | 문자열을 다루는 함수들은 자바에 있는 함수나 스스로 만드는 것보다는 1166 | `clojure.string`의 함수를 쓰는 것이 좋다. 1167 | [[link](#prefer-clojure-string-over-interop)] 1168 | 1169 | ```Clojure 1170 | ;; 좋은 예 1171 | (clojure.string/upper-case "bruce") 1172 | 1173 | ;; 나쁜 예 1174 | (.toUpperCase "bruce") 1175 | ``` 1176 | 1177 | ## 예외 1178 | 1179 | * 1180 | 가능하면 자바에 있는 예외 타입을 사용하라. 기본 타입(예. `java.lang.IllegalArgumentException`, 1181 | `java.lang.UnsupportedOperationException`, 1182 | `java.lang.IllegalStateException`, `java.io.IOException`)의 예외를 던지는 것이 1183 | 일반적인 클로저 코드이다. 1184 | [[link](#reuse-existing-exception-types)] 1185 | 1186 | * 1187 | `finally`보다는 `with-open`을 권장한다. 1188 | [[link](#prefer-with-open-over-finally)] 1189 | 1190 | ## 매크로 1191 | 1192 | * 1193 | 함수로 가능한 것을 매크로로 만들지 마라. 1194 | [[link](#dont-write-macro-if-fn-will-do)] 1195 | 1196 | * 1197 | 매크로 다음에 매크로를 생성하는 예제를 만들어라. 1198 | [[link](#write-macro-usage-before-writing-the-macro)] 1199 | 1200 | * 1201 | 복잡한 매크로는 가능하다면 좀더 작은 함수들로 분리하라. 1202 | [[link](#break-complicated-macros)] 1203 | 1204 | * 1205 | 매크로는 깔끔한 문법을 제공해야 하고 구현이 의존성 없는 함수로 이루어져아한다. 1206 | 그래야 재사용성을 향상시킬 수 있다. 1207 | [[link](#macros-as-syntactic-sugar)] 1208 | 1209 | * 1210 | 그냥 매크로를 작성하는 것 보다 Syntax-quoted 구문을 사용을 권장한다. 1211 | [[link](#syntax-quoted-forms)] 1212 | 1213 | ## 주석 1214 | 1215 | > 좋은 코드는 그 자체가 좋은 문서이다. 주석을 달기 전에 스스로에게 물어봐라, "어떻게 하면 이 주석이 필요없게 1216 | > 코드를 개선할 수 있을까?" 코드를 개선해서 문서처럼 보이게 하는 것이다.
1217 | > -- Steve McConnell 1218 | 1219 | * 1220 | 가능하면 코드가 스스로 문서화가 될 수 있도록 노력한다. 1221 | [[link](#self-documenting-code)] 1222 | 1223 | * 1224 | 제목을 나타내는 주석은 최소한 4개의 세미콜론을 사용하여 작성한다. 1225 | [[link](#four-semicolons-for-heading-comments)] 1226 | 1227 | * 1228 | 소개를 나타내는 주석은 3개의 세미콜론을 사용하여 작성한다. 1229 | [[link](#three-semicolons-for-top-level-comments)] 1230 | 1231 | * 1232 | 코드의 특정 부분을 설명하는 주석은 그 코드와 들여쓰기를 맞추고 세미콜론 2개를 사용하여 작성한다. 1233 | [[link](#two-semicolons-for-code-fragment)] 1234 | 1235 | * 1236 | 코드의 끝에 오는 주석은 세미콜론 하나를 사용해서 작성한다. 1237 | [[link](#one-semicolon-for-margin-comments)] 1238 | 1239 | * 1240 | 세미콜론과 주석 내용은 항상 최소 한개의 공백을 두고 작성한다. 1241 | [[link](#semicolon-space)] 1242 | 1243 | ```Clojure 1244 | ;;;; Frob Grovel 1245 | 1246 | ;;; This section of code has some important implications: 1247 | ;;; 1. Foo. 1248 | ;;; 2. Bar. 1249 | ;;; 3. Baz. 1250 | 1251 | (defn fnord [zarquon] 1252 | ;; If zob, then veeblefitz. 1253 | (quux zot 1254 | mumble ; Zibblefrotz. 1255 | frotz)) 1256 | ``` 1257 | 1258 | * 1259 | 한 단어 이상의 주석은 대문자로 시작하고 마침표를 사용한다. 문장의 구분은 1260 | [공백하나](http://en.wikipedia.org/wiki/Sentence_spacing)를 사용한다. 1261 | [[link](#english-syntax)] 1262 | 1263 | * 1264 | 쓸데없는 주석은 피한다. 1265 | [[link](#no-superfluous-comments)] 1266 | 1267 | ```Clojure 1268 | ;; 나쁜 예 1269 | (inc counter) ; increments counter by one 1270 | ``` 1271 | 1272 | * 1273 | 주석은 항상 최신 상태로 유지한다. 업데이트 되지 않은 주석은 없는 게 좋다. 1274 | [[link](#comment-upkeep)] 1275 | 1276 | * 1277 | 구문을 유지해야하는 경우에는 주석 보다는 `#_` 리더 매크로 사용을 권장한다. 1278 | [[link](#dash-underscore-reader-macro)] 1279 | 1280 | ```Clojure 1281 | ;; 좋은 예 1282 | (+ foo #_(bar x) delta) 1283 | 1284 | ;; 나쁜 예 1285 | (+ foo 1286 | ;; (bar x) 1287 | delta) 1288 | ``` 1289 | 1290 | > 좋은 코드는 좋은 농담과 같다 - 설명이 필요없다.
1291 | > -- Russ Olsen 1292 | 1293 | * 1294 | 나쁜 코드에 대해 설명하는 주석은 피한다. 스스로 문서화가 될 수 있도록 코드를 리팩토링한다. 1295 | (하거나 안하거나 둘 중 하나다. - '시험삼아 한다'는 것은 없다. -- Yoda) 1296 | [[link](#refactor-dont-comment)] 1297 | 1298 | ### 주석어노테이션 1299 | 1300 | * 1301 | 어노테이션은 관련된 코드 바로 위에 작성한다. 1302 | [[link](#annotate-above)] 1303 | 1304 | * 1305 | 어노테이션 키워드는 콜론과 공백 다음에 설명을 작성한다. 1306 | [[link](#annotate-keywords)] 1307 | 1308 | * 1309 | 만약 설명이 여러줄인 경우 다음 줄은 설명의 첫번째와 들여쓰기를 맞춘다. 1310 | [[link](#indent-annotations)] 1311 | 1312 | * 1313 | 주석에 관련된 날짜를 태그형식으로 달면 나중에 쉽게 확인 할 수 있다. 1314 | [[link](#sing-and-date-annotations)] 1315 | 1316 | ```Clojure 1317 | (defn some-fun 1318 | [] 1319 | ;; FIXME: This has crashed occasionally since v1.2.3. It may 1320 | ;; be related to the BarBazUtil upgrade. (xz 13-1-31) 1321 | (baz)) 1322 | ``` 1323 | 1324 | * 1325 | 설명이 명확하지 않고 중복되는 경우 예외적으로 라인 뒷쪽에 어노테이션을 작성합니다. (규칙은 아님) 1326 | [[link](#rare-eol-annotations)] 1327 | 1328 | ```Clojure 1329 | (defn bar 1330 | [] 1331 | (sleep 100)) ; OPTIMIZE 1332 | ``` 1333 | 1334 | * 1335 | `TODO`는 구현되지 않은 기능을 나중에 추가해야할 때 사용한다. 1336 | [[link](#todo)] 1337 | 1338 | * 1339 | `FIXME`는 코드가 잘못되어서 고쳐야할 때 사용한다. 1340 | [[link](#fixme)] 1341 | 1342 | * 1343 | `OPTIMIZE`는 코드가 느리거나 비효율적이라서 성능상 문제가 생기는 경우에 사용한다. 1344 | [[link](#optimize)] 1345 | 1346 | * 1347 | `HACK`은 코드에 냄새가 나는 것 같아 리팩토링이 필요한 경우 사용한다. 1348 | [[link](#hack)] 1349 | 1350 | * 1351 | `REVIEW`는 의도한대로 동작하는지 확인해야하는 경우에 사용한다. 1352 | 예: 1353 | ``` 1354 | `REVIEW: Are we sure this is how the client does X currently?`` 1355 | ``` 1356 | [[link](#review)] 1357 | 1358 | * 1359 | 다른 어노테이션 키워들은 필요에 따라 작성하고 `README` 같은 곳에 정리해둔다. 1360 | [[link](#document-annotations)] 1361 | 1362 | ## 문서화 1363 | 1364 | Docstring은 클로저 코드를 문서화하는 기본적인 방법이다. 여러 정의 구문은 docstring을 지원하고 1365 | (예: `def`, `defn`, `defmacro`, `ns`) var가 공개든 비공개든 상관 없이 docstring을 잘 1366 | 사용하는 것이 좋다. 1367 | 1368 | Docstring을 지원하지 않는 경우에는 `:doc` 메타데이터 속성에 추가하면 된다. 1369 | 1370 | 이 장은 클로저 코드를 문서화하는 일반적인 컨벤션과 잘 사용한 예를 다룬다. 1371 | 1372 | * 1373 | 만약 구문이 docstring을 직접 지원하면 `:doc` 메타데이터를 사용하기 보다 직접 지원하는 docstring을 1374 | 사용한다. 1375 | [[link](#prefer-docstrings)] 1376 | 1377 | ```clojure 1378 | ;; 좋은 예 1379 | (defn foo 1380 | "This function doesn't do much." 1381 | [] 1382 | ...) 1383 | 1384 | (ns foo.bar.core 1385 | "That's an awesome library.") 1386 | 1387 | ;; 나쁜 예 1388 | (defn foo 1389 | ^{:doc "This function doesn't do much."} 1390 | [] 1391 | ...) 1392 | 1393 | (ns ^{:doc "That's an awesome library.") 1394 | foo.bar.core) 1395 | ``` 1396 | 1397 | * 1398 | docstring의 첫번째 줄은 대문자로 시작하며 var를 간결하게 설명하는 완전한 문장으로 작성한다. 1399 | 그렇게 하면 Clojure 에디터나 IDE 같은 툴의 다양한 곳에서 쉽게 docstring 요약을 보여줄 수 있다. 1400 | [[link](#docstring-summary)] 1401 | 1402 | ```clojure 1403 | ;; 좋은 예 1404 | (defn frobnitz 1405 | "This function does a frobnitz. 1406 | It will do gnorwatz to achieve this, but only under certain 1407 | cricumstances." 1408 | [] 1409 | ...) 1410 | 1411 | ;; 나쁜 예 1412 | (defn frobnitz 1413 | "This function does a frobnitz. It will do gnorwatz to 1414 | achieve this, but only under certain cricumstances." 1415 | [] 1416 | ...) 1417 | ``` 1418 | 1419 | * 1420 | 모든 위치의 인자를 문서화하고 백틱(\`)으로 감싼다. 그래야 에디터나 IDE가 인식해서 잠재적 추가 기능을 1421 | 제공할 수 있다. 1422 | [[link](#document-pos-arguments)] 1423 | 1424 | ```clojure 1425 | ;; 좋은 예 1426 | (defn watsitz 1427 | "Watsitz takes a `frob` and converts it to a znoot. 1428 | When the `frob` is negative, the znoot becomes angry." 1429 | [frob] 1430 | ...) 1431 | 1432 | ;; 나쁜 예 1433 | (defn watsitz 1434 | "Watsitz takes a frob and converts it to a znoot. 1435 | When the frob is negative, the znoot becomes angry." 1436 | [frob] 1437 | ...) 1438 | ``` 1439 | 1440 | * 1441 | docstring에 var 참조가 있는 경우 툴에서 사용할 수 있도록 \`와 함께 쓴다. 1442 | [[link](#document-references)] 1443 | 1444 | ```clojure 1445 | ;; 좋은 예 1446 | (defn wombat 1447 | "Acts much like `clojure.core/identity` except when it doesn't. 1448 | Takes `x` as an argument and returns that. If it feels like it." 1449 | [x] 1450 | ...) 1451 | 1452 | ;; 나쁜 예 1453 | (defn wombat 1454 | "Acts much like clojure.core/identity except when it doesn't. 1455 | Takes `x` as an argument and returns that. If it feels like it." 1456 | [x] 1457 | ...) 1458 | ``` 1459 | 1460 | * docstring은 적절한 영어 구문으로 되어 있어야 한다. 그래서 1461 | 문장은 대문자로 시작하며 적절한 부호로 마쳐야한다. 또 문장은 공백 하나로 구분 되어야 한다. 1462 | [[link](#docstring-grammar)] 1463 | 1464 | ```clojure 1465 | ;; 좋은 예 1466 | (def foo 1467 | "All sentences should end with a period (or maybe an exclamation mark). 1468 | And the period should be followed by a space, unless it's the last sentence.") 1469 | 1470 | ;; 나쁜 예 1471 | (def foo 1472 | "all sentences should end with a period (or maybe an exclamation mark). 1473 | And the period should be followed by a space, unless it's the last sentence") 1474 | ``` 1475 | 1476 | * 1477 | docstring이 여러 줄이면 두개의 공백으로 들여쓰기한다. 1478 | [[link](#docstring-indentation)] 1479 | 1480 | ```clojure 1481 | ;; 좋은 예 1482 | (ns my.ns 1483 | "It is actually possible to document a ns. 1484 | It's a nice place to describe the purpose of the namespace and maybe even 1485 | the overall conventions used. Note how _not_ indenting the doc string makes 1486 | it easier for tooling to display it correctly.") 1487 | 1488 | ;; 나쁜 예 1489 | (ns my.ns 1490 | "It is actually possible to document a ns. 1491 | It's a nice place to describe the purpose of the namespace and maybe even 1492 | the overall conventions used. Note how _not_ indenting the doc string makes 1493 | it easier for tooling to display it correctly.") 1494 | ``` 1495 | 1496 | * 1497 | doc string 앞 뒤에는 공백을 사용하지 않는다. 1498 | [[link](#docstring-leading-trailing-whitespace)] 1499 | 1500 | ```clojure 1501 | ;; 좋은 예 1502 | (def foo 1503 | "I'm so awesome." 1504 | 42) 1505 | 1506 | ;; 나쁜 예 1507 | (def silly 1508 | " It's just silly to start a doc string with spaces. 1509 | Just as silly as it is to end it with a bunch of them. " 1510 | 42) 1511 | ``` 1512 | 1513 | * 1514 | docstring을 넣을 때 (특히 폼 위에 함수에) 인자 백터 다음에 오지 않고 함수 이름 다음에 오도록 1515 | 주의한다. 백터 다음에 오게 해도 오류가 발생하지 않지만 docstring에 추가되지 않고 함수의 본문에 있는 1516 | 문자열로 인식되버린다. 1517 | [[link](#docstring-after-fn-name)] 1518 | 1519 | ```Clojure 1520 | ;; 좋은 예 1521 | (defn foo 1522 | "docstring" 1523 | [x] 1524 | (bar x)) 1525 | 1526 | ;; 나쁜 예 1527 | (defn foo [x] 1528 | "docstring" 1529 | (bar x)) 1530 | ``` 1531 | 1532 | ## 그밖에 1533 | 1534 | * 1535 | 가능하면 상태변경을 피하고, 함수형 방식을 사용하라. 1536 | [[link](#be-functional)] 1537 | 1538 | * 1539 | 일관성을 지켜라. 이 가이드라인의 가지고 일관성을 유지하는 것이 좋다. 1540 | [[link](#be-consistent)] 1541 | 1542 | * 1543 | 상식에 맞게 해라. 1544 | [[link](#common-sense)] 1545 | 1546 | ## 도구들 1547 | 1548 | 클로저 커뮤니티에서 만들어진 코딩스타일을 위한 몇개의 툴이 있다. 1549 | 1550 | * [Slamhound](https://github.com/technomancy/slamhound)는 기존에 작성된 코드에 필요한 ns를 1551 | 자동으로 생성해준다. 1552 | * [kibit](https://github.com/jonase/kibit)은 [core.logic](https://github.com/clojure/core.logic)에서 1553 | 일반적으로 사용되는 함수나 매크로등의 코드 패턴을 기반으로, 정적 코드 분석을 해주는 툴이다. 1554 | 1555 | ## 테스트 1556 | 1557 | * 1558 | 테스트 코드는 분리된 디렉토리에 저장한다. 보통 `src/yourproject/` 대신 `test/yourproject/`에 저장한다. 1559 | 빌드 툴은 필요한 컨텍스트 안에서 이 파일들을 처리할 책임이 있다; 대부분의 템플릿은 이것을 자동으로 준다. 1560 | [[link](#test-directory-structure)] 1561 | 1562 | * 1563 | 테스트 네임스페이스는 `yourproject.something-test`과 같이 이름 붙이고 파일은 보통 1564 | `test/yourproject/something_test.clj`(또는 `.cljc`, `.cljs`)로 만든다. 1565 | [[link](#test-ns-naming)] 1566 | 1567 | * `clojure.test`를 사용할 때 `deftest`를 사용해 정의하는 테스트는 1568 | `something-test`로 이름을 붙인다. 1569 | ```clojure 1570 | ;; 좋은 예 1571 | (deftest something-test ...) 1572 | 1573 | ;; 나쁜 예 1574 | (deftest something-tests ...) 1575 | (deftest test-something ...) 1576 | (deftest something ...) 1577 | ``` 1578 | [[link](#test-naming)] 1579 | 1580 | # 참여하기 1581 | 1582 | 이 가이드는 완성된 가이드가 아니다. 클로저 코딩 스타일에 흥미를 가지고 있는 사람들과 함께 만들고 싶다. 1583 | 그래서 모든 클로저 커뮤니티에서 잘 사용되면 좋겠다. 1584 | 1585 | 이 문서를 고치려면, 티켓을 열거나 풀리퀘스트를 보내라. 미리 ㄱㅅㄱㅅ 1586 | 1587 | 프로젝트에 금전적인 기부는 [gittip](https://www.gittip.com/bbatsov)을 통해 할 수 있다. 1588 | 1589 | [![Support via Gittip](https://rawgithub.com/twolfson/gittip-badge/0.2.0/dist/gittip.png)](https://www.gittip.com/bbatsov) 1590 | 1591 | # 라이센스 1592 | 1593 | ![Creative Commons License](http://i.creativecommons.org/l/by/3.0/88x31.png) 1594 | [Creative Commons Attribution 3.0 Unported License](http://creativecommons.org/licenses/by/3.0/deed.en_US)에 1595 | 따라 이용가능하다. 1596 | 1597 | # 공유합시다! 1598 | 1599 | 커뮤니티 기반 스타일 가이드는 알려질수록 좋다. 1600 | 이 가이드를 친구나 동료들에게 트윗하거나 공유하라. 1601 | 댓글이나 의견, 제안은 가이드를 좀 더 좋게 만들 수 있다. 1602 | 자네, 더 좋은 가이드를 가지고 싶지 않은가? 1603 | 1604 | 화이팅,
1605 | [Bozhidar](https://twitter.com/bbatsov) 1606 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The Clojure Style Guide 2 | 3 | > Role models are important.
4 | > -- Officer Alex J. Murphy / RoboCop 5 | 6 | This Clojure style guide recommends best practices so that real-world Clojure 7 | programmers can write code that can be maintained by other real-world Clojure 8 | programmers. A style guide that reflects real-world usage gets used, and a 9 | style guide that holds to an ideal that has been rejected by the people it is 10 | supposed to help risks not getting used at all — no matter how good it is. 11 | 12 | The guide is separated into several sections of related rules. I've 13 | tried to add the rationale behind the rules (if it's omitted, I've 14 | assumed that it's pretty obvious). 15 | 16 | I didn't come up with all the rules out of nowhere; they are mostly 17 | based on my extensive career as a professional software engineer, 18 | feedback and suggestions from members of the Clojure community, and 19 | various highly regarded Clojure programming resources, such as 20 | ["Clojure Programming"](http://www.clojurebook.com/) 21 | and ["The Joy of Clojure"](http://joyofclojure.com/). 22 | 23 | The guide is still a work in progress; some sections are missing, 24 | others are incomplete, some rules are lacking examples, some rules 25 | don't have examples that illustrate them clearly enough. In due time 26 | these issues will be addressed — just keep them in mind for now. 27 | 28 | Please note, that the Clojure developing community maintains a list of 29 | [coding standards for libraries](http://dev.clojure.org/display/community/Library+Coding+Standards), 30 | too. 31 | 32 | You can generate a PDF or an HTML copy of this guide using 33 | [Pandoc](http://pandoc.org/). 34 | 35 | Translations of the guide are available in the following languages: 36 | 37 | * [Chinese](https://github.com/geekerzp/clojure-style-guide/blob/master/README-zhCN.md) 38 | * [Japanese](https://github.com/totakke/clojure-style-guide/blob/ja/README.md) 39 | * [Korean](https://github.com/kwakbab/clojure-style-guide/blob/master/README-koKO.md) 40 | * [Portuguese](https://github.com/theSkilled/clojure-style-guide/blob/pt-BR/README.md) (Under progress) 41 | * [Russian](https://github.com/Nondv/clojure-style-guide/blob/master/ru/README.md) 42 | 43 | ## Table of Contents 44 | 45 | * [Source Code Layout & Organization](#source-code-layout--organization) 46 | * [Syntax](#syntax) 47 | * [Naming](#naming) 48 | * [Collections](#collections) 49 | * [Mutation](#mutation) 50 | * [Strings](#strings) 51 | * [Exceptions](#exceptions) 52 | * [Macros](#macros) 53 | * [Comments](#comments) 54 | * [Comment Annotations](#comment-annotations) 55 | * [Documentation](#documentation) 56 | * [Existential](#existential) 57 | * [Tooling](#tooling) 58 | * [Testing](#testing) 59 | * [Library Organization](#library-organization) 60 | 61 | ## Source Code Layout & Organization 62 | 63 | > Nearly everybody is convinced that every style but their own is 64 | > ugly and unreadable. Leave out the "but their own" and they're 65 | > probably right...
66 | > -- Jerry Coffin (on indentation) 67 | 68 | * 69 | Use **spaces** for indentation. No hard tabs. 70 | [[link](#spaces)] 71 | 72 | * 73 | Use 2 spaces to indent the bodies of 74 | forms that have body parameters. This covers all `def` forms, special 75 | forms and macros that introduce local bindings (e.g. `loop`, `let`, 76 | `when-let`) and many macros like `when`, `cond`, `as->`, `cond->`, `case`, 77 | `with-*`, etc. 78 | [[link](#body-indentation)] 79 | 80 | 81 | ```Clojure 82 | ;; good 83 | (when something 84 | (something-else)) 85 | 86 | (with-out-str 87 | (println "Hello, ") 88 | (println "world!")) 89 | 90 | ;; bad - four spaces 91 | (when something 92 | (something-else)) 93 | 94 | ;; bad - one space 95 | (with-out-str 96 | (println "Hello, ") 97 | (println "world!")) 98 | ``` 99 | 100 | * 101 | Vertically align function (macro) arguments spanning multiple lines. 102 | [[link](#vertically-align-fn-args)] 103 | 104 | ```Clojure 105 | ;; good 106 | (filter even? 107 | (range 1 10)) 108 | 109 | ;; bad 110 | (filter even? 111 | (range 1 10)) 112 | ``` 113 | 114 | * 115 | Use a single space indentation for function (macro) arguments 116 | when there are no arguments on the same line as the function name. 117 | [[link](#one-space-indent)] 118 | 119 | ```Clojure 120 | ;; good 121 | (filter 122 | even? 123 | (range 1 10)) 124 | 125 | (or 126 | ala 127 | bala 128 | portokala) 129 | 130 | ;; bad - two-space indent 131 | (filter 132 | even? 133 | (range 1 10)) 134 | 135 | (or 136 | ala 137 | bala 138 | portokala) 139 | ``` 140 | 141 | * 142 | Vertically align `let` bindings and map keywords. 143 | [[link](#vertically-align-let-and-map)] 144 | 145 | ```Clojure 146 | ;; good 147 | (let [thing1 "some stuff" 148 | thing2 "other stuff"] 149 | {:thing1 thing1 150 | :thing2 thing2}) 151 | 152 | ;; bad 153 | (let [thing1 "some stuff" 154 | thing2 "other stuff"] 155 | {:thing1 thing1 156 | :thing2 thing2}) 157 | ``` 158 | 159 | * 160 | Optionally omit the new line between the function name and argument 161 | vector for `defn` when there is no docstring. 162 | [[link](#optional-new-line-after-fn-name)] 163 | 164 | ```Clojure 165 | ;; good 166 | (defn foo 167 | [x] 168 | (bar x)) 169 | 170 | ;; good 171 | (defn foo [x] 172 | (bar x)) 173 | 174 | ;; bad 175 | (defn foo 176 | [x] (bar x)) 177 | ``` 178 | 179 | * 180 | Place the `dispatch-val` of a multimethod on the same line as the 181 | function name. 182 | [[link](#multimethod-dispatch-val-placement)] 183 | 184 | 185 | ```Clojure 186 | ;; good 187 | (defmethod foo :bar [x] (baz x)) 188 | 189 | (defmethod foo :bar 190 | [x] 191 | (baz x)) 192 | 193 | ;; bad 194 | (defmethod foo 195 | :bar 196 | [x] 197 | (baz x)) 198 | 199 | (defmethod foo 200 | :bar [x] 201 | (baz x)) 202 | ``` 203 | 204 | * 205 | Optionally omit the new line between the argument vector and a short 206 | function body. 207 | [[link](#oneline-short-fn)] 208 | 209 | ```Clojure 210 | ;; good 211 | (defn foo [x] 212 | (bar x)) 213 | 214 | ;; good for a small function body 215 | (defn foo [x] (bar x)) 216 | 217 | ;; good for multi-arity functions 218 | (defn foo 219 | ([x] (bar x)) 220 | ([x y] 221 | (if (predicate? x) 222 | (bar x) 223 | (baz x)))) 224 | 225 | ;; bad 226 | (defn foo 227 | [x] (if (predicate? x) 228 | (bar x) 229 | (baz x))) 230 | ``` 231 | 232 | * 233 | Indent each arity form of a function definition vertically aligned with its 234 | parameters.[[link](#multiple-arity-indentation)] 235 | 236 | ```Clojure 237 | ;; good 238 | (defn foo 239 | "I have two arities." 240 | ([x] 241 | (foo x 1)) 242 | ([x y] 243 | (+ x y))) 244 | 245 | ;; bad - extra indentation 246 | (defn foo 247 | "I have two arities." 248 | ([x] 249 | (foo x 1)) 250 | ([x y] 251 | (+ x y))) 252 | ``` 253 | 254 | * Sort the arities of a function 255 | from fewest to most arguments. The common case of multi-arity 256 | functions is that some K arguments fully specifies the function's 257 | behavior, and that arities N < K partially apply the K arity, and 258 | arities N > K provide a fold of the K arity over varargs. 259 | [[link](#multiple-arity-order)] 260 | 261 | ```Clojure 262 | ;; good - it's easy to scan for the nth arity 263 | (defn foo 264 | "I have two arities." 265 | ([x] 266 | (foo x 1)) 267 | ([x y] 268 | (+ x y))) 269 | 270 | ;; okay - the other arities are applications of the two-arity 271 | (defn foo 272 | "I have two arities." 273 | ([x y] 274 | (+ x y)) 275 | ([x] 276 | (foo x 1)) 277 | ([x y z & more] 278 | (reduce foo (foo x (foo y z)) more))) 279 | 280 | ;; bad - unordered for no apparent reason 281 | (defn foo 282 | ([x] 1) 283 | ([x y z] (foo x (foo y z))) 284 | ([x y] (+ x y)) 285 | ([w x y z & more] (reduce foo (foo w (foo x (foo y z))) more))) 286 | ``` 287 | 288 | * 289 | Use Unix-style line endings. (*BSD/Solaris/Linux/OSX users are 290 | covered by default, Windows users have to be extra careful.) 291 | [[link](#crlf)] 292 | 293 | * If you're using Git you might want to add the following 294 | configuration setting to protect your project from Windows line 295 | endings creeping in: 296 | 297 | ``` 298 | bash$ git config --global core.autocrlf true 299 | ``` 300 | 301 | * 302 | If any text precedes an opening bracket(`(`, `{` and 303 | `[`) or follows a closing bracket(`)`, `}` and `]`), separate that 304 | text from that bracket with a space. Conversely, leave no space after 305 | an opening bracket and before following text, or after preceding text 306 | and before a closing bracket. 307 | [[link](#bracket-spacing)] 308 | 309 | ```Clojure 310 | ;; good 311 | (foo (bar baz) quux) 312 | 313 | ;; bad 314 | (foo(bar baz)quux) 315 | (foo ( bar baz ) quux) 316 | ``` 317 | 318 | > Syntactic sugar causes semicolon cancer.
319 | > -- Alan Perlis 320 | 321 | * 322 | Don't use commas between the elements of sequential collection literals. 323 | [[link](#no-commas-for-seq-literals)] 324 | 325 | ```Clojure 326 | ;; good 327 | [1 2 3] 328 | (1 2 3) 329 | 330 | ;; bad 331 | [1, 2, 3] 332 | (1, 2, 3) 333 | ``` 334 | 335 | * 336 | Consider enhancing the readability of map literals via judicious use 337 | of commas and line breaks. 338 | [[link](#opt-commas-in-map-literals)] 339 | 340 | ```Clojure 341 | ;; good 342 | {:name "Bruce Wayne" :alter-ego "Batman"} 343 | 344 | ;; good and arguably a bit more readable 345 | {:name "Bruce Wayne" 346 | :alter-ego "Batman"} 347 | 348 | ;; good and arguably more compact 349 | {:name "Bruce Wayne", :alter-ego "Batman"} 350 | ``` 351 | 352 | * 353 | Place all trailing parentheses on a single line instead of distinct lines. 354 | [[link](#gather-trailing-parens)] 355 | 356 | ```Clojure 357 | ;; good; single line 358 | (when something 359 | (something-else)) 360 | 361 | ;; bad; distinct lines 362 | (when something 363 | (something-else) 364 | ) 365 | ``` 366 | 367 | * 368 | Use empty lines between top-level forms. 369 | [[link](#empty-lines-between-top-level-forms)] 370 | 371 | ```Clojure 372 | ;; good 373 | (def x ...) 374 | 375 | (defn foo ...) 376 | 377 | ;; bad 378 | (def x ...) 379 | (defn foo ...) 380 | ``` 381 | 382 | An exception to the rule is the grouping of related `def`s together. 383 | 384 | ```Clojure 385 | ;; good 386 | (def min-rows 10) 387 | (def max-rows 20) 388 | (def min-cols 15) 389 | (def max-cols 30) 390 | ``` 391 | 392 | * 393 | Do not place blank lines in the middle of a function or 394 | macro definition. An exception can be made to indicate grouping of 395 | pairwise constructs as found in e.g. `let` and `cond`. 396 | [[link](#no-blank-lines-within-def-forms)] 397 | 398 | * 399 | Where feasible, avoid making lines longer than 80 characters. 400 | [[link](#80-character-limits)] 401 | 402 | * 403 | Avoid trailing whitespace. 404 | [[link](#no-trailing-whitespace)] 405 | 406 | * 407 | Use one file per namespace. 408 | [[link](#one-file-per-namespace)] 409 | 410 | * 411 | Start every namespace with a comprehensive `ns` form, comprised of 412 | `refer`s, `require`s, and `import`s, conventionally in that order. 413 | [[link](#comprehensive-ns-declaration)] 414 | 415 | ```Clojure 416 | (ns examples.ns 417 | (:refer-clojure :exclude [next replace remove]) 418 | (:require [clojure.string :as s :refer [blank?]] 419 | [clojure.set :as set] 420 | [clojure.java.shell :as sh]) 421 | (:import java.util.Date 422 | java.text.SimpleDateFormat 423 | [java.util.concurrent Executors 424 | LinkedBlockingQueue])) 425 | ``` 426 | 427 | * 428 | In the `ns` form prefer `:require :as` over `:require :refer` over `:require 429 | :refer :all`. Prefer `:require` over `:use`; the latter form should be 430 | considered deprecated for new code. 431 | [[link](#prefer-require-over-use)] 432 | 433 | ```Clojure 434 | ;; good 435 | (ns examples.ns 436 | (:require [clojure.zip :as zip])) 437 | 438 | ;; good 439 | (ns examples.ns 440 | (:require [clojure.zip :refer [lefts rights]])) 441 | 442 | ;; acceptable as warranted 443 | (ns examples.ns 444 | (:require [clojure.zip :refer :all])) 445 | 446 | ;; bad 447 | (ns examples.ns 448 | (:use clojure.zip)) 449 | ``` 450 | 451 | * 452 | Avoid single-segment namespaces. 453 | [[link](#no-single-segment-namespaces)] 454 | 455 | ```Clojure 456 | ;; good 457 | (ns example.ns) 458 | 459 | ;; bad 460 | (ns example) 461 | ``` 462 | 463 | * 464 | Avoid the use of overly long namespaces (i.e., more than 5 segments). 465 | [[link](#namespaces-with-5-segments-max)] 466 | 467 | * 468 | Avoid functions longer than 10 LOC (lines of code). Ideally, most 469 | functions will be shorter than 5 LOC. 470 | [[link](#10-loc-per-fn-limit)] 471 | 472 | * 473 | Avoid parameter lists with more than three or four positional parameters. 474 | [[link](#4-positional-fn-params-limit)] 475 | 476 | * 477 | Avoid forward references. They are occasionally necessary, but such occasions 478 | are rare in practice. 479 | [[link](#forward-references)] 480 | 481 | ## Syntax 482 | 483 | * 484 | Avoid the use of namespace-manipulating functions like `require` and 485 | `refer`. They are entirely unnecessary outside of a REPL 486 | environment. 487 | [[link](#ns-fns-only-in-repl)] 488 | 489 | * 490 | Use `declare` to enable forward references when forward references are 491 | necessary. 492 | [[link](#declare)] 493 | 494 | * 495 | Prefer higher-order functions like `map` to `loop/recur`. 496 | [[link](#higher-order-fns)] 497 | 498 | * 499 | Prefer function pre and post conditions to checks inside a function's body. 500 | [[link](#pre-post-conditions)] 501 | 502 | ```Clojure 503 | ;; good 504 | (defn foo [x] 505 | {:pre [(pos? x)]} 506 | (bar x)) 507 | 508 | ;; bad 509 | (defn foo [x] 510 | (if (pos? x) 511 | (bar x) 512 | (throw (IllegalArgumentException. "x must be a positive number!"))) 513 | ``` 514 | 515 | * 516 | Don't define vars inside functions. 517 | [[link](#dont-def-vars-inside-fns)] 518 | 519 | ```Clojure 520 | ;; very bad 521 | (defn foo [] 522 | (def x 5) 523 | ...) 524 | ``` 525 | 526 | * 527 | Don't shadow `clojure.core` names with local bindings. 528 | [[link](#dont-shadow-clojure-core)] 529 | 530 | ```Clojure 531 | ;; bad - you're forced to use clojure.core/map fully qualified inside 532 | (defn foo [map] 533 | ...) 534 | ``` 535 | 536 | * 537 | Use `alter-var-root` instead of `def` to change the value of a var. 538 | [[link]](#alter-var) 539 | 540 | ```Clojure 541 | ;; good 542 | (def thing 1) ; value of thing is now 1 543 | ; do some stuff with thing 544 | (alter-var-root #'thing (constantly nil)) ; value of thing is now nil 545 | 546 | ;; bad 547 | (def thing 1) 548 | ; do some stuff with thing 549 | (def thing nil) 550 | ; value of thing is now nil 551 | ``` 552 | 553 | * 554 | Use `seq` as a terminating condition to test whether a sequence is 555 | empty (this technique is sometimes called *nil punning*). 556 | [[link](#nil-punning)] 557 | 558 | ```Clojure 559 | ;; good 560 | (defn print-seq [s] 561 | (when (seq s) 562 | (prn (first s)) 563 | (recur (rest s)))) 564 | 565 | ;; bad 566 | (defn print-seq [s] 567 | (when-not (empty? s) 568 | (prn (first s)) 569 | (recur (rest s)))) 570 | ``` 571 | 572 | * 573 | Prefer `vec` over `into` when you need to convert a sequence into a vector. 574 | [[link](#to-vector)] 575 | 576 | ```Clojure 577 | ;; good 578 | (vec some-seq) 579 | 580 | ;; bad 581 | (into [] some-seq) 582 | ``` 583 | 584 | * 585 | Use `when` instead of `(if ... (do ...)`. 586 | [[link](#when-instead-of-single-branch-if)] 587 | 588 | ```Clojure 589 | ;; good 590 | (when pred 591 | (foo) 592 | (bar)) 593 | 594 | ;; bad 595 | (if pred 596 | (do 597 | (foo) 598 | (bar))) 599 | ``` 600 | 601 | * 602 | Use `if-let` instead of `let` + `if`. 603 | [[link](#if-let)] 604 | 605 | ```Clojure 606 | ;; good 607 | (if-let [result (foo x)] 608 | (something-with result) 609 | (something-else)) 610 | 611 | ;; bad 612 | (let [result (foo x)] 613 | (if result 614 | (something-with result) 615 | (something-else))) 616 | ``` 617 | 618 | * 619 | Use `when-let` instead of `let` + `when`. 620 | [[link](#when-let)] 621 | 622 | ```Clojure 623 | ;; good 624 | (when-let [result (foo x)] 625 | (do-something-with result) 626 | (do-something-more-with result)) 627 | 628 | ;; bad 629 | (let [result (foo x)] 630 | (when result 631 | (do-something-with result) 632 | (do-something-more-with result))) 633 | ``` 634 | 635 | * 636 | Use `if-not` instead of `(if (not ...) ...)`. 637 | [[link](#if-not)] 638 | 639 | ```Clojure 640 | ;; good 641 | (if-not pred 642 | (foo)) 643 | 644 | ;; bad 645 | (if (not pred) 646 | (foo)) 647 | ``` 648 | 649 | * 650 | Use `when-not` instead of `(when (not ...) ...)`. 651 | [[link](#when-not)] 652 | 653 | ```Clojure 654 | ;; good 655 | (when-not pred 656 | (foo) 657 | (bar)) 658 | 659 | ;; bad 660 | (when (not pred) 661 | (foo) 662 | (bar)) 663 | ``` 664 | 665 | * 666 | Use `when-not` instead of `(if-not ... (do ...)`. 667 | [[link](#when-not-instead-of-single-branch-if-not)] 668 | 669 | ```Clojure 670 | ;; good 671 | (when-not pred 672 | (foo) 673 | (bar)) 674 | 675 | ;; bad 676 | (if-not pred 677 | (do 678 | (foo) 679 | (bar))) 680 | ``` 681 | 682 | * 683 | Use `not=` instead of `(not (= ...))`. 684 | [[link](#not-equal)] 685 | 686 | ```Clojure 687 | ;; good 688 | (not= foo bar) 689 | 690 | ;; bad 691 | (not (= foo bar)) 692 | ``` 693 | 694 | * 695 | Use `printf` instead of `(print (format ...))`. 696 | [[link](#printf)] 697 | 698 | ```Clojure 699 | ;; good 700 | (printf "Hello, %s!\n" name) 701 | 702 | ;; ok 703 | (println (format "Hello, %s!" name)) 704 | ``` 705 | 706 | * 707 | When doing comparisons, keep in mind that Clojure's functions `<`, 708 | `>`, etc. accept a variable number of arguments. 709 | [[link](#multiple-arity-of-gt-and-ls-fns)] 710 | 711 | ```Clojure 712 | ;; good 713 | (< 5 x 10) 714 | 715 | ;; bad 716 | (and (> x 5) (< x 10)) 717 | ``` 718 | 719 | * 720 | Prefer `%` over `%1` in function literals with only one parameter. 721 | [[link](#single-param-fn-literal)] 722 | 723 | ```Clojure 724 | ;; good 725 | #(Math/round %) 726 | 727 | ;; bad 728 | #(Math/round %1) 729 | ``` 730 | 731 | * 732 | Prefer `%1` over `%` in function literals with more than one parameter. 733 | [[link](#multiple-params-fn-literal)] 734 | 735 | ```Clojure 736 | ;; good 737 | #(Math/pow %1 %2) 738 | 739 | ;; bad 740 | #(Math/pow % %2) 741 | ``` 742 | 743 | * 744 | Don't wrap functions in anonymous functions when you don't need to. 745 | [[link](#no-useless-anonymous-fns)] 746 | 747 | ```Clojure 748 | ;; good 749 | (filter even? (range 1 10)) 750 | 751 | ;; bad 752 | (filter #(even? %) (range 1 10)) 753 | ``` 754 | 755 | * 756 | Don't use function literals if the function body will consist of 757 | more than one form. 758 | [[link](#no-multiple-forms-fn-literals)] 759 | 760 | ```Clojure 761 | ;; good 762 | (fn [x] 763 | (println x) 764 | (* x 2)) 765 | 766 | ;; bad (you need an explicit do form) 767 | #(do (println %) 768 | (* % 2)) 769 | ``` 770 | 771 | * 772 | Favor the use of `complement` versus the use of an anonymous function. 773 | [[link](#complement)] 774 | 775 | ```Clojure 776 | ;; good 777 | (filter (complement some-pred?) coll) 778 | 779 | ;; bad 780 | (filter #(not (some-pred? %)) coll) 781 | ``` 782 | 783 | This rule should obviously be ignored if the complementing predicate 784 | exists in the form of a separate function (e.g. `even?` and `odd?`). 785 | 786 | * 787 | Leverage `comp` when doing so yields simpler code. 788 | [[link](#comp)] 789 | 790 | ```Clojure 791 | ;; Assuming `(:require [clojure.string :as str])`... 792 | 793 | ;; good 794 | (map #(str/capitalize (str/trim %)) ["top " " test "]) 795 | 796 | ;; better 797 | (map (comp str/capitalize str/trim) ["top " " test "]) 798 | ``` 799 | 800 | * 801 | Leverage `partial` when doing so yields simpler code. 802 | [[link](#partial)] 803 | 804 | ```Clojure 805 | ;; good 806 | (map #(+ 5 %) (range 1 10)) 807 | 808 | ;; (arguably) better 809 | (map (partial + 5) (range 1 10)) 810 | ``` 811 | 812 | * 813 | Prefer the use of the threading macros `->` (thread-first) and `->>` 814 | (thread-last) to heavy form nesting. 815 | [[link](#threading-macros)] 816 | 817 | ```Clojure 818 | ;; good 819 | (-> [1 2 3] 820 | reverse 821 | (conj 4) 822 | prn) 823 | 824 | ;; not as good 825 | (prn (conj (reverse [1 2 3]) 826 | 4)) 827 | 828 | ;; good 829 | (->> (range 1 10) 830 | (filter even?) 831 | (map (partial * 2))) 832 | 833 | ;; not as good 834 | (map (partial * 2) 835 | (filter even? (range 1 10))) 836 | ``` 837 | 838 | * 839 | Use `:else` as the catch-all test expression in `cond`. 840 | [[link](#else-keyword-in-cond)] 841 | 842 | ```Clojure 843 | ;; good 844 | (cond 845 | (neg? n) "negative" 846 | (pos? n) "positive" 847 | :else "zero") 848 | 849 | ;; bad 850 | (cond 851 | (neg? n) "negative" 852 | (pos? n) "positive" 853 | true "zero") 854 | ``` 855 | 856 | * 857 | Prefer `condp` instead of `cond` when the predicate & expression don't 858 | change. 859 | [[link](#condp)] 860 | 861 | ```Clojure 862 | ;; good 863 | (cond 864 | (= x 10) :ten 865 | (= x 20) :twenty 866 | (= x 30) :thirty 867 | :else :dunno) 868 | 869 | ;; much better 870 | (condp = x 871 | 10 :ten 872 | 20 :twenty 873 | 30 :thirty 874 | :dunno) 875 | ``` 876 | 877 | * 878 | Prefer `case` instead of `cond` or `condp` when test expressions are 879 | compile-time constants. 880 | [[link](#case)] 881 | 882 | ```Clojure 883 | ;; good 884 | (cond 885 | (= x 10) :ten 886 | (= x 20) :twenty 887 | (= x 30) :forty 888 | :else :dunno) 889 | 890 | ;; better 891 | (condp = x 892 | 10 :ten 893 | 20 :twenty 894 | 30 :forty 895 | :dunno) 896 | 897 | ;; best 898 | (case x 899 | 10 :ten 900 | 20 :twenty 901 | 30 :forty 902 | :dunno) 903 | ``` 904 | 905 | * 906 | Use short forms in `cond` and related. If not possible give visual 907 | hints for the pairwise grouping with comments or empty lines. 908 | [[link](#shor-forms-in-cond)] 909 | 910 | ```Clojure 911 | ;; good 912 | (cond 913 | (test1) (action1) 914 | (test2) (action2) 915 | :else (default-action)) 916 | 917 | ;; ok-ish 918 | (cond 919 | ;; test case 1 920 | (test1) 921 | (long-function-name-which-requires-a-new-line 922 | (complicated-sub-form 923 | (-> 'which-spans multiple-lines))) 924 | 925 | ;; test case 2 926 | (test2) 927 | (another-very-long-function-name 928 | (yet-another-sub-form 929 | (-> 'which-spans multiple-lines))) 930 | 931 | :else 932 | (the-fall-through-default-case 933 | (which-also-spans 'multiple 934 | 'lines))) 935 | ``` 936 | 937 | * 938 | Use a `set` as a predicate when appropriate. 939 | [[link](#set-as-predicate)] 940 | 941 | ```Clojure 942 | ;; good 943 | (remove #{1} [0 1 2 3 4 5]) 944 | 945 | ;; bad 946 | (remove #(= % 1) [0 1 2 3 4 5]) 947 | 948 | ;; good 949 | (count (filter #{\a \e \i \o \u} "mary had a little lamb")) 950 | 951 | ;; bad 952 | (count (filter #(or (= % \a) 953 | (= % \e) 954 | (= % \i) 955 | (= % \o) 956 | (= % \u)) 957 | "mary had a little lamb")) 958 | ``` 959 | 960 | * 961 | Use `(inc x)` & `(dec x)` instead of `(+ x 1)` and `(- x 1)`. 962 | [[link](#inc-and-dec)] 963 | 964 | * 965 | Use `(pos? x)`, `(neg? x)` & `(zero? x)` instead of `(> x 0)`, 966 | `(< x 0)` & `(= x 0)`. 967 | [[link](#pos-and-neg)] 968 | 969 | * 970 | Use `list*` instead of a series of nested `cons` invocations. 971 | [[link](#list-star-instead-of-nested-cons)] 972 | 973 | ```Clojure 974 | ;; good 975 | (list* 1 2 3 [4 5]) 976 | 977 | ;; bad 978 | (cons 1 (cons 2 (cons 3 [4 5]))) 979 | ``` 980 | 981 | * 982 | Use the sugared Java interop forms. 983 | [[link](#sugared-java-interop)] 984 | 985 | ```Clojure 986 | ;;; object creation 987 | ;; good 988 | (java.util.ArrayList. 100) 989 | 990 | ;; bad 991 | (new java.util.ArrayList 100) 992 | 993 | ;;; static method invocation 994 | ;; good 995 | (Math/pow 2 10) 996 | 997 | ;; bad 998 | (. Math pow 2 10) 999 | 1000 | ;;; instance method invocation 1001 | ;; good 1002 | (.substring "hello" 1 3) 1003 | 1004 | ;; bad 1005 | (. "hello" substring 1 3) 1006 | 1007 | ;;; static field access 1008 | ;; good 1009 | Integer/MAX_VALUE 1010 | 1011 | ;; bad 1012 | (. Integer MAX_VALUE) 1013 | 1014 | ;;; instance field access 1015 | ;; good 1016 | (.someField some-object) 1017 | 1018 | ;; bad 1019 | (. some-object someField) 1020 | ``` 1021 | 1022 | * 1023 | Use the compact metadata notation for metadata that contains only 1024 | slots whose keys are keywords and whose value is boolean `true`. 1025 | [[link](#compact-metadata-notation-for-true-flags)] 1026 | 1027 | ```Clojure 1028 | ;; good 1029 | (def ^:private a 5) 1030 | 1031 | ;; bad 1032 | (def ^{:private true} a 5) 1033 | ``` 1034 | 1035 | * 1036 | Denote private parts of your code. 1037 | [[link](#private)] 1038 | 1039 | ```Clojure 1040 | ;; good 1041 | (defn- private-fun [] ...) 1042 | 1043 | (def ^:private private-var ...) 1044 | 1045 | ;; bad 1046 | (defn private-fun [] ...) ; not private at all 1047 | 1048 | (defn ^:private private-fun [] ...) ; overly verbose 1049 | 1050 | (def private-var ...) ; not private at all 1051 | ``` 1052 | 1053 | * 1054 | To access a private var (e.g. for testing), use the `@#'some.ns/var` form. 1055 | [[link](#access-private-var)] 1056 | 1057 | * 1058 | Be careful regarding what exactly do you attach metadata to. 1059 | [[link](#attach-metadata-carefully)] 1060 | 1061 | ```Clojure 1062 | ;; we attach the metadata to the var referenced by `a` 1063 | (def ^:private a {}) 1064 | (meta a) ;=> nil 1065 | (meta #'a) ;=> {:private true} 1066 | 1067 | ;; we attach the metadata to the empty hash-map value 1068 | (def a ^:private {}) 1069 | (meta a) ;=> {:private true} 1070 | (meta #'a) ;=> nil 1071 | ``` 1072 | 1073 | ## Naming 1074 | 1075 | > The only real difficulties in programming are cache invalidation and 1076 | > naming things.
1077 | > -- Phil Karlton 1078 | 1079 | * 1080 | When naming namespaces favor the following two schemas: 1081 | [[link](#ns-naming-schemas)] 1082 | 1083 | * `project.module` 1084 | * `organization.project.module` 1085 | 1086 | * 1087 | Use `lisp-case` in composite namespace segments(e.g. `bruce.project-euler`) 1088 | [[link](#lisp-case-ns)] 1089 | 1090 | * 1091 | Use `lisp-case` for function and variable names. 1092 | [[link](#lisp-case)] 1093 | 1094 | ```Clojure 1095 | ;; good 1096 | (def some-var ...) 1097 | (defn some-fun ...) 1098 | 1099 | ;; bad 1100 | (def someVar ...) 1101 | (defn somefun ...) 1102 | (def some_fun ...) 1103 | ``` 1104 | 1105 | * 1106 | Use `CamelCase` for protocols, records, structs, and types. (Keep 1107 | acronyms like HTTP, RFC, XML uppercase.) 1108 | [[link](#CamelCase-for-protocols-records-structs-and-types)] 1109 | 1110 | * 1111 | The names of predicate methods (methods that return a boolean value) 1112 | should end in a question mark 1113 | (e.g., `even?`). 1114 | [[link](#pred-with-question-mark)] 1115 | 1116 | ```Clojure 1117 | ;; good 1118 | (defn palindrome? ...) 1119 | 1120 | ;; bad 1121 | (defn palindrome-p ...) ; Common Lisp style 1122 | (defn is-palindrome ...) ; Java style 1123 | ``` 1124 | 1125 | * 1126 | The names of functions/macros that are not safe in STM transactions 1127 | should end with an exclamation mark (e.g. `reset!`). 1128 | [[link](#changing-state-fns-with-exclamation-mark)] 1129 | 1130 | * 1131 | Use `->` instead of `to` in the names of conversion functions. 1132 | [[link](#arrow-instead-of-to)] 1133 | 1134 | ```Clojure 1135 | ;; good 1136 | (defn f->c ...) 1137 | 1138 | ;; not so good 1139 | (defn f-to-c ...) 1140 | ``` 1141 | 1142 | * 1143 | Use `*earmuffs*` for things intended for rebinding (ie. are dynamic). 1144 | [[link](#earmuffs-for-dynamic-vars)] 1145 | 1146 | ```Clojure 1147 | ;; good 1148 | (def ^:dynamic *a* 10) 1149 | 1150 | ;; bad 1151 | (def ^:dynamic a 10) 1152 | ``` 1153 | 1154 | * 1155 | Don't use a special notation for constants; everything is assumed a constant 1156 | unless specified otherwise. 1157 | [[link](#dont-flag-constants)] 1158 | 1159 | * 1160 | Use `_` for destructuring targets and formal argument names whose 1161 | value will be ignored by the code at hand. 1162 | [[link](#underscore-for-unused-bindings)] 1163 | 1164 | ```Clojure 1165 | ;; good 1166 | (let [[a b _ c] [1 2 3 4]] 1167 | (println a b c)) 1168 | 1169 | (dotimes [_ 3] 1170 | (println "Hello!")) 1171 | 1172 | ;; bad 1173 | (let [[a b c d] [1 2 3 4]] 1174 | (println a b d)) 1175 | 1176 | (dotimes [i 3] 1177 | (println "Hello!")) 1178 | ``` 1179 | 1180 | * 1181 | Follow `clojure.core`'s example for idiomatic names like `pred` and `coll`. 1182 | [[link](#idiomatic-names)] 1183 | 1184 | * in functions: 1185 | * `f`, `g`, `h` - function input 1186 | * `n` - integer input usually a size 1187 | * `index`, `i` - integer index 1188 | * `x`, `y` - numbers 1189 | * `xs` - sequence 1190 | * `m` - map 1191 | * `s` - string input 1192 | * `re` - regular expression 1193 | * `coll` - a collection 1194 | * `pred` - a predicate closure 1195 | * `& more` - variadic input 1196 | * `xf` - xform, a transducer 1197 | * in macros: 1198 | * `expr` - an expression 1199 | * `body` - a macro body 1200 | * `binding` - a macro binding vector 1201 | 1202 | ## Collections 1203 | 1204 | > It is better to have 100 functions operate on one data structure 1205 | > than to have 10 functions operate on 10 data structures.
1206 | > -- Alan J. Perlis 1207 | 1208 | * 1209 | Avoid the use of lists for generic data storage (unless a list is 1210 | exactly what you need). 1211 | [[link](#avoid-lists)] 1212 | 1213 | * 1214 | Prefer the use of keywords for hash keys. 1215 | [[link](#keywords-for-hash-keys)] 1216 | 1217 | ```Clojure 1218 | ;; good 1219 | {:name "Bruce" :age 30} 1220 | 1221 | ;; bad 1222 | {"name" "Bruce" "age" 30} 1223 | ``` 1224 | 1225 | * 1226 | Prefer the use of the literal collection syntax where 1227 | applicable. However, when defining sets, only use literal syntax 1228 | when the values are compile-time constants. 1229 | [[link](#literal-col-syntax)] 1230 | 1231 | ```Clojure 1232 | ;; good 1233 | [1 2 3] 1234 | #{1 2 3} 1235 | (hash-set (func1) (func2)) ; values determined at runtime 1236 | 1237 | ;; bad 1238 | (vector 1 2 3) 1239 | (hash-set 1 2 3) 1240 | #{(func1) (func2)} ; will throw runtime exception if (func1) = (func2) 1241 | ``` 1242 | 1243 | * 1244 | Avoid accessing collection members by index whenever possible. 1245 | [[link](#avoid-index-based-coll-access)] 1246 | 1247 | * 1248 | Prefer the use of keywords as functions for retrieving values from 1249 | maps, where applicable. 1250 | [[link](#keywords-as-fn-to-get-map-values)] 1251 | 1252 | ```Clojure 1253 | (def m {:name "Bruce" :age 30}) 1254 | 1255 | ;; good 1256 | (:name m) 1257 | 1258 | ;; more verbose than necessary 1259 | (get m :name) 1260 | 1261 | ;; bad - susceptible to NullPointerException 1262 | (m :name) 1263 | ``` 1264 | 1265 | * 1266 | Leverage the fact that most collections are functions of their elements. 1267 | [[link](#colls-as-fns)] 1268 | 1269 | ```Clojure 1270 | ;; good 1271 | (filter #{\a \e \o \i \u} "this is a test") 1272 | 1273 | ;; bad - too ugly to share 1274 | ``` 1275 | 1276 | * 1277 | Leverage the fact that keywords can be used as functions of a collection. 1278 | [[link](#keywords-as-fns)] 1279 | 1280 | ```Clojure 1281 | ((juxt :a :b) {:a "ala" :b "bala"}) 1282 | ``` 1283 | 1284 | * 1285 | Avoid the use of transient collections, except for 1286 | performance-critical portions of the code. 1287 | [[link](#avoid-transient-colls)] 1288 | 1289 | * 1290 | Avoid the use of Java collections. 1291 | [[link](#avoid-java-colls)] 1292 | 1293 | * 1294 | Avoid the use of Java arrays, except for interop scenarios and 1295 | performance-critical code dealing heavily with primitive types. 1296 | [[link](#avoid-java-arrays)] 1297 | 1298 | ## Mutation 1299 | 1300 | ### Refs 1301 | 1302 | * 1303 | Consider wrapping all I/O calls with the `io!` macro to avoid nasty 1304 | surprises if you accidentally end up calling such code in a 1305 | transaction. 1306 | [[link](#refs-io-macro)] 1307 | 1308 | * 1309 | Avoid the use of `ref-set` whenever possible. 1310 | [[link](#refs-avoid-ref-set)] 1311 | 1312 | ```Clojure 1313 | (def r (ref 0)) 1314 | 1315 | ;; good 1316 | (dosync (alter r + 5)) 1317 | 1318 | ;; bad 1319 | (dosync (ref-set r 5)) 1320 | ``` 1321 | 1322 | * 1323 | Try to keep the size of transactions (the amount of work encapsulated in them) 1324 | as small as possible. 1325 | [[link](#refs-small-transactions)] 1326 | 1327 | * 1328 | Avoid having both short- and long-running transactions interacting 1329 | with the same Ref. 1330 | [[link](#refs-avoid-short-long-transactions-with-same-ref)] 1331 | 1332 | ### Agents 1333 | 1334 | * 1335 | Use `send` only for actions that are CPU bound and don't block on I/O 1336 | or other threads. 1337 | [[link](#agents-send)] 1338 | 1339 | * 1340 | Use `send-off` for actions that might block, sleep, or otherwise tie 1341 | up the thread. 1342 | [[link](#agents-send-off)] 1343 | 1344 | ### Atoms 1345 | 1346 | * 1347 | Avoid atom updates inside STM transactions. 1348 | [[link](#atoms-no-update-within-transactions)] 1349 | 1350 | * 1351 | Try to use `swap!` rather than `reset!`, where possible. 1352 | [[link](#atoms-prefer-swap-over-reset)] 1353 | 1354 | ```Clojure 1355 | (def a (atom 0)) 1356 | 1357 | ;; good 1358 | (swap! a + 5) 1359 | 1360 | ;; not as good 1361 | (reset! a 5) 1362 | ``` 1363 | 1364 | ## Strings 1365 | 1366 | * 1367 | Prefer string manipulation functions from `clojure.string` over Java interop or rolling your own. 1368 | [[link](#prefer-clojure-string-over-interop)] 1369 | 1370 | ```Clojure 1371 | ;; good 1372 | (clojure.string/upper-case "bruce") 1373 | 1374 | ;; bad 1375 | (.toUpperCase "bruce") 1376 | ``` 1377 | 1378 | ## Exceptions 1379 | 1380 | * 1381 | Reuse existing exception types. Idiomatic Clojure code — when it does 1382 | throw an exception — throws an exception of a standard type 1383 | (e.g. `java.lang.IllegalArgumentException`, 1384 | `java.lang.UnsupportedOperationException`, 1385 | `java.lang.IllegalStateException`, `java.io.IOException`). 1386 | [[link](#reuse-existing-exception-types)] 1387 | 1388 | * 1389 | Favor `with-open` over `finally`. 1390 | [[link](#prefer-with-open-over-finally)] 1391 | 1392 | ## Macros 1393 | 1394 | * 1395 | Don't write a macro if a function will do. 1396 | [[link](#dont-write-macro-if-fn-will-do)] 1397 | 1398 | * 1399 | Create an example of a macro usage first and the macro afterwards. 1400 | [[link](#write-macro-usage-before-writing-the-macro)] 1401 | 1402 | * 1403 | Break complicated macros into smaller functions whenever possible. 1404 | [[link](#break-complicated-macros)] 1405 | 1406 | * 1407 | A macro should usually just provide syntactic sugar and the core of 1408 | the macro should be a plain function. Doing so will improve 1409 | composability. 1410 | [[link](#macros-as-syntactic-sugar)] 1411 | 1412 | * 1413 | Prefer syntax-quoted forms over building lists manually. 1414 | [[link](#syntax-quoted-forms)] 1415 | 1416 | ## Comments 1417 | 1418 | > Good code is its own best documentation. As you're about to add a 1419 | > comment, ask yourself, "How can I improve the code so that this 1420 | > comment isn't needed?" Improve the code and then document it to make 1421 | > it even clearer.
1422 | > -- Steve McConnell 1423 | 1424 | * 1425 | Endeavor to make your code as self-documenting as possible. 1426 | [[link](#self-documenting-code)] 1427 | 1428 | * 1429 | Write heading comments with at least four semicolons. 1430 | [[link](#four-semicolons-for-heading-comments)] 1431 | 1432 | * 1433 | Write top-level comments with three semicolons. 1434 | [[link](#three-semicolons-for-top-level-comments)] 1435 | 1436 | * 1437 | Write comments on a particular fragment of code before that fragment 1438 | and aligned with it, using two semicolons. 1439 | [[link](#two-semicolons-for-code-fragment)] 1440 | 1441 | * 1442 | Write margin comments with one semicolon. 1443 | [[link](#one-semicolon-for-margin-comments)] 1444 | 1445 | * 1446 | Always have at least one space between the semicolon 1447 | and the text that follows it. 1448 | [[link](#semicolon-space)] 1449 | 1450 | ```Clojure 1451 | ;;;; Frob Grovel 1452 | 1453 | ;;; This section of code has some important implications: 1454 | ;;; 1. Foo. 1455 | ;;; 2. Bar. 1456 | ;;; 3. Baz. 1457 | 1458 | (defn fnord [zarquon] 1459 | ;; If zob, then veeblefitz. 1460 | (quux zot 1461 | mumble ; Zibblefrotz. 1462 | frotz)) 1463 | ``` 1464 | 1465 | * 1466 | Comments longer than a word begin with a capital letter and use 1467 | punctuation. Separate sentences with 1468 | [one space](http://en.wikipedia.org/wiki/Sentence_spacing). 1469 | [[link](#english-syntax)] 1470 | 1471 | * 1472 | Avoid superfluous comments. 1473 | [[link](#no-superfluous-comments)] 1474 | 1475 | ```Clojure 1476 | ;; bad 1477 | (inc counter) ; increments counter by one 1478 | ``` 1479 | 1480 | * 1481 | Keep existing comments up-to-date. An outdated comment is worse than no comment 1482 | at all. 1483 | [[link](#comment-upkeep)] 1484 | 1485 | * 1486 | Prefer the use of the `#_` reader macro over a regular comment when 1487 | you need to comment out a particular form. 1488 | [[link](#dash-underscore-reader-macro)] 1489 | 1490 | ```Clojure 1491 | ;; good 1492 | (+ foo #_(bar x) delta) 1493 | 1494 | ;; bad 1495 | (+ foo 1496 | ;; (bar x) 1497 | delta) 1498 | ``` 1499 | 1500 | > Good code is like a good joke - it needs no explanation.
1501 | > -- Russ Olsen 1502 | 1503 | * 1504 | Avoid writing comments to explain bad code. Refactor the code to 1505 | make it self-explanatory. ("Do, or do not. There is no try." --Yoda) 1506 | [[link](#refactor-dont-comment)] 1507 | 1508 | ### Comment Annotations 1509 | 1510 | * 1511 | Annotations should usually be written on the line immediately above 1512 | the relevant code. 1513 | [[link](#annotate-above)] 1514 | 1515 | * 1516 | The annotation keyword is followed by a colon and a space, then a note 1517 | describing the problem. 1518 | [[link](#annotate-keywords)] 1519 | 1520 | * 1521 | If multiple lines are required to describe the problem, subsequent 1522 | lines should be indented as much as the first one. 1523 | [[link](#indent-annotations)] 1524 | 1525 | * 1526 | Tag the annotation with your initials and a date so its relevance can 1527 | be easily verified. 1528 | [[link](#sing-and-date-annotations)] 1529 | 1530 | ```Clojure 1531 | (defn some-fun 1532 | [] 1533 | ;; FIXME: This has crashed occasionally since v1.2.3. It may 1534 | ;; be related to the BarBazUtil upgrade. (xz 13-1-31) 1535 | (baz)) 1536 | ``` 1537 | 1538 | * 1539 | In cases where the problem is so obvious that any documentation would 1540 | be redundant, annotations may be left at the end of the offending line 1541 | with no note. This usage should be the exception and not the rule. 1542 | [[link](#rare-eol-annotations)] 1543 | 1544 | ```Clojure 1545 | (defn bar 1546 | [] 1547 | (sleep 100)) ; OPTIMIZE 1548 | ``` 1549 | 1550 | * 1551 | Use `TODO` to note missing features or functionality that should be 1552 | added at a later date. 1553 | [[link](#todo)] 1554 | 1555 | * 1556 | Use `FIXME` to note broken code that needs to be fixed. 1557 | [[link](#fixme)] 1558 | 1559 | * 1560 | Use `OPTIMIZE` to note slow or inefficient code that may cause 1561 | performance problems. 1562 | [[link](#optimize)] 1563 | 1564 | * 1565 | Use `HACK` to note "code smells" where questionable coding practices 1566 | were used and should be refactored away. 1567 | [[link](#hack)] 1568 | 1569 | * 1570 | Use `REVIEW` to note anything that should be looked at to confirm it 1571 | is working as intended. For example: `REVIEW: Are we sure this is how the 1572 | client does X currently?` 1573 | [[link](#review)] 1574 | 1575 | * 1576 | Use other custom annotation keywords if it feels appropriate, but be 1577 | sure to document them in your project's `README` or similar. 1578 | [[link](#document-annotations)] 1579 | 1580 | ## Documentation 1581 | 1582 | Docstrings are the primary way to document Clojure code. Many definition forms 1583 | (e.g. `def`, `defn`, `defmacro`, `ns`) 1584 | support docstrings and usually it's a good idea to make good use of them, regardless 1585 | of whether the var in question is something public or private. 1586 | 1587 | If a definition form doesn't support docstrings directly you can still supply them via 1588 | the `:doc` metadata attribute. 1589 | 1590 | This section outlines some of the common conventions and best 1591 | practices for documenting Clojure code. 1592 | 1593 | 1594 | * 1595 | If a form supports docstrings directly prefer them over using `:doc` metadata: 1596 | [[link](#prefer-docstrings)] 1597 | 1598 | ```clojure 1599 | ;; good 1600 | (defn foo 1601 | "This function doesn't do much." 1602 | [] 1603 | ...) 1604 | 1605 | (ns foo.bar.core 1606 | "That's an awesome library.") 1607 | 1608 | ;; bad 1609 | (defn foo 1610 | ^{:doc "This function doesn't do much."} 1611 | [] 1612 | ...) 1613 | 1614 | (ns ^{:doc "That's an awesome library.") 1615 | foo.bar.core) 1616 | ``` 1617 | 1618 | * 1619 | Let the first line in the doc string be a complete, capitalized 1620 | sentence which concisely describes the var in question. This makes it 1621 | easy for tooling (Clojure editors and IDEs) to display a short a summary of 1622 | the docstring at various places. 1623 | [[link](#docstring-summary)] 1624 | 1625 | ```clojure 1626 | ;; good 1627 | (defn frobnitz 1628 | "This function does a frobnitz. 1629 | It will do gnorwatz to achieve this, but only under certain 1630 | cricumstances." 1631 | [] 1632 | ...) 1633 | 1634 | ;; bad 1635 | (defn frobnitz 1636 | "This function does a frobnitz. It will do gnorwatz to 1637 | achieve this, but only under certain cricumstances." 1638 | [] 1639 | ...) 1640 | ``` 1641 | 1642 | * 1643 | Document all positional arguments, and wrap them them with backticks 1644 | (\`) so that editors and IDEs can identify them and potentially provide extra 1645 | functionality for them. 1646 | [[link](#document-pos-arguments)] 1647 | 1648 | ```clojure 1649 | ;; good 1650 | (defn watsitz 1651 | "Watsitz takes a `frob` and converts it to a znoot. 1652 | When the `frob` is negative, the znoot becomes angry." 1653 | [frob] 1654 | ...) 1655 | 1656 | ;; bad 1657 | (defn watsitz 1658 | "Watsitz takes a frob and converts it to a znoot. 1659 | When the frob is negative, the znoot becomes angry." 1660 | [frob] 1661 | ...) 1662 | ``` 1663 | 1664 | * 1665 | Wrap any var references in the docstring with \` so that tooling 1666 | can identify them. 1667 | [[link](#document-references)] 1668 | 1669 | ```clojure 1670 | ;; good 1671 | (defn wombat 1672 | "Acts much like `clojure.core/identity` except when it doesn't. 1673 | Takes `x` as an argument and returns that. If it feels like it." 1674 | [x] 1675 | ...) 1676 | 1677 | ;; bad 1678 | (defn wombat 1679 | "Acts much like clojure.core/identity except when it doesn't. 1680 | Takes `x` as an argument and returns that. If it feels like it." 1681 | [x] 1682 | ...) 1683 | ``` 1684 | 1685 | * Docstrings should be comprised from 1686 | proper English sentences - this means every sentences should start 1687 | with an capitalized word and should end with the proper punctuation. Sentences 1688 | should be separated with a single space. 1689 | [[link](#docstring-grammar)] 1690 | 1691 | ```clojure 1692 | ;; good 1693 | (def foo 1694 | "All sentences should end with a period (or maybe an exclamation mark). 1695 | And the period should be followed by a space, unless it's the last sentence.") 1696 | 1697 | ;; bad 1698 | (def foo 1699 | "all sentences should end with a period (or maybe an exclamation mark). 1700 | And the period should be followed by a space, unless it's the last sentence") 1701 | ``` 1702 | 1703 | * 1704 | Indent multi-line docstrings by two spaces. 1705 | [[link](#docstring-indentation)] 1706 | 1707 | ```clojure 1708 | ;; good 1709 | (ns my.ns 1710 | "It is actually possible to document a ns. 1711 | It's a nice place to describe the purpose of the namespace and maybe even 1712 | the overall conventions used. Note how _not_ indenting the doc string makes 1713 | it easier for tooling to display it correctly.") 1714 | 1715 | ;; bad 1716 | (ns my.ns 1717 | "It is actually possible to document a ns. 1718 | It's a nice place to describe the purpose of the namespace and maybe even 1719 | the overall conventions used. Note how _not_ indenting the doc string makes 1720 | it easier for tooling to display it correctly.") 1721 | ``` 1722 | 1723 | * 1724 | Neither start nor end your doc strings with any whitespace. 1725 | [[link](#docstring-leading-trailing-whitespace)] 1726 | 1727 | ```clojure 1728 | ;; good 1729 | (def foo 1730 | "I'm so awesome." 1731 | 42) 1732 | 1733 | ;; bad 1734 | (def silly 1735 | " It's just silly to start a doc string with spaces. 1736 | Just as silly as it is to end it with a bunch of them. " 1737 | 42) 1738 | ``` 1739 | 1740 | * 1741 | When adding a docstring – especially to a function using the above form – take 1742 | care to correctly place the docstring after the function name, not after the 1743 | argument vector. The latter is not invalid syntax and won’t cause an error, 1744 | but includes the string as a form in the function body without attaching it to 1745 | the var as documentation. 1746 | [[link](#docstring-after-fn-name)] 1747 | 1748 | ```Clojure 1749 | ;; good 1750 | (defn foo 1751 | "docstring" 1752 | [x] 1753 | (bar x)) 1754 | 1755 | ;; bad 1756 | (defn foo [x] 1757 | "docstring" 1758 | (bar x)) 1759 | ``` 1760 | 1761 | ## Existential 1762 | 1763 | * 1764 | Code in a functional way, using mutation only when it makes sense. 1765 | [[link](#be-functional)] 1766 | 1767 | * 1768 | Be consistent. In an ideal world, be consistent with these guidelines. 1769 | [[link](#be-consistent)] 1770 | 1771 | * 1772 | Use common sense. 1773 | [[link](#common-sense)] 1774 | 1775 | ## Tooling 1776 | 1777 | There are some tools created by the Clojure community that might aid you 1778 | in your endeavor to write idiomatic Clojure code. 1779 | 1780 | * [Slamhound](https://github.com/technomancy/slamhound) is a tool that will 1781 | automatically generate proper `ns` declarations from your existing code. 1782 | 1783 | * [kibit](https://github.com/jonase/kibit) is a static code analyzer for 1784 | Clojure which uses [core.logic](https://github.com/clojure/core.logic) to 1785 | search for patterns of code for which there might exist a more idiomatic 1786 | function or macro. 1787 | 1788 | ## Testing 1789 | 1790 | * 1791 | Store your tests in a separate directory, typically `test/yourproject/` (as 1792 | opposed to `src/yourproject/`). Your build tool is responsible for making 1793 | them available in the contexts where they are necessary; most templates 1794 | will do this for you automatically. 1795 | [[link](#test-directory-structure)] 1796 | 1797 | * 1798 | Name your ns `yourproject.something-test`, a file which usually lives in 1799 | `test/yourproject/something_test.clj` (or `.cljc`, `cljs`). 1800 | [[link](#test-ns-naming)] 1801 | 1802 | * 1803 | When using `clojure.test`, define your tests 1804 | with `deftest` and name them `something-test`. 1805 | [[link](#test-naming)] 1806 | 1807 | ```clojure 1808 | ;; good 1809 | (deftest something-test ...) 1810 | 1811 | ;; bad 1812 | (deftest something-tests ...) 1813 | (deftest test-something ...) 1814 | (deftest something ...) 1815 | ``` 1816 | 1817 | ## Library Organization 1818 | 1819 | * 1820 | If you are publishing libraries to be used by others, make sure to 1821 | follow the [Central Repository 1822 | guidelines](http://central.sonatype.org/pages/choosing-your-coordinates.html) 1823 | for choosing your `groupId` and `artifactId`. This helps to prevent 1824 | name conflicts and facilitates the widest possible use. A good 1825 | example is [Component](https://github.com/stuartsierra/component). 1826 | [[link](#lib-coordinates)] 1827 | 1828 | * 1829 | Avoid unnecessary dependencies. For example, a three-line utility 1830 | function copied into a project is usually better than a dependency 1831 | that drags in hundreds of vars you do not plan to use. 1832 | [[link](#lib-min-dependencies)] 1833 | 1834 | * 1835 | Deliver core functionality and integration points in separate 1836 | artifacts. That way, consumers can consume your library without 1837 | being constrained by your unrelated tooling prefences. For example, 1838 | [Component](https://github.com/stuartsierra/component) provides 1839 | core functionality, and 1840 | [reloaded](https://github.com/stuartsierra/reloaded) provides leiningen 1841 | integration. 1842 | [[link](#lib-core-separate-from-tools)] 1843 | 1844 | # Contributing 1845 | 1846 | Nothing written in this guide is set in stone. It's my desire to work 1847 | together with everyone interested in Clojure coding style, so that we could 1848 | ultimately create a resource that will be beneficial to the entire Clojure 1849 | community. 1850 | 1851 | Feel free to open tickets or send pull requests with improvements. Thanks in 1852 | advance for your help! 1853 | 1854 | You can also support the style guide with financial 1855 | contributions via [gittip](https://www.gittip.com/bbatsov). 1856 | 1857 | [![Support via Gittip](https://rawgithub.com/twolfson/gittip-badge/0.2.0/dist/gittip.png)](https://www.gittip.com/bbatsov) 1858 | 1859 | # License 1860 | 1861 | ![Creative Commons License](http://i.creativecommons.org/l/by/3.0/88x31.png) 1862 | This work is licensed under a 1863 | [Creative Commons Attribution 3.0 Unported License](http://creativecommons.org/licenses/by/3.0/deed.en_US) 1864 | 1865 | # Spread the Word 1866 | 1867 | A community-driven style guide is of little use to a community that 1868 | doesn't know about its existence. Tweet about the guide, share it with 1869 | your friends and colleagues. Every comment, suggestion or opinion we 1870 | get makes the guide just a little bit better. And we want to have the 1871 | best possible guide, don't we? 1872 | 1873 | Cheers,
1874 | [Bozhidar](https://twitter.com/bbatsov) 1875 | --------------------------------------------------------------------------------