├── CONTRIBUTING.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.md: -------------------------------------------------------------------------------- 1 | # Guia de estilo Clojure 2 | 3 | > Os modelos são importantes.
4 | > -- Oficial Alex J. Murphy / RoboCop 5 | 6 | Este guia de estilo recomenda melhores práticas para que programadores Clojure possam escrever códigos e possam ser mantidos por outros programadores. A style guide that reflects real-world usage gets used, and a 7 | style guide that holds to an ideal that has been rejected by the people it is 8 | supposed to help risks not getting used at all — não importa quão bom ele seja. 9 | 10 | O guia está dividido em várias seções de regras relacionadas. Eu tentei adicionar toda a lógica por trás das regras (Se for omitido, estou assumindo que é bastante óbvio). 11 | 12 | Eu não apareci com todas as regras do nada; elas foram feitas principalmente com base na minha extensa carreira como engenheiro de software profissional, 13 | feedback e sugestões de membros da comunidade Clojure, and various highly regarded Clojure programming resources, como 14 | ["Clojure Programming"](http://www.clojurebook.com/) 15 | e ["The Joy of Clojure"](http://joyofclojure.com/). 16 | 17 | O guia ainda é um trabalho em andamento; está faltando algumas seções, outras estão incompletas, algumas regras faltam exemplos, outras não tem exemplos que as ilustre bem o suficiente. Estas questões seram abordadas em seu devido tempo — Apenas mantenha-os em mente por enquanto. 18 | 19 | Por favor, notem que a comunidade de desenvolvedores do Clojure também mantém uma [lista de padrões de codificação](http://dev.clojure.org/display/community/Library+Coding+Standards) para as bibliotecas. 20 | 21 | Você pode gerar uma cópia em PDF ou em HTML deste guia usando o [Pandoc](http://pandoc.org/). 22 | 23 | Traduções deste guia estão disponíveis também nas seguintes linguagens: 24 | 25 | * [Inglês](https://github.com/bbatsov/clojure-style-guide) 26 | * [Chinês](https://github.com/geekerzp/clojure-style-guide/blob/master/README-zhCN.md) 27 | * [Japonês](https://github.com/totakke/clojure-style-guide/blob/ja/README.md) 28 | * [Coreano](https://github.com/kwakbab/clojure-style-guide/blob/master/README-koKO.md) 29 | * [Russo](https://github.com/Nondv/clojure-style-guide/blob/master/ru/README.md) 30 | * [Espanhol](https://github.com/jeko2000/clojure-style-guide/blob/master/README.md) 31 | 32 | ## Índice 33 | 34 | * [Disposição do código & Organização](#disposição-do-código--organização) 35 | * [Sintaxe](#sintaxe) 36 | * [Nomenclaturas](#nomenclaturas) 37 | * [Collections](#collections) 38 | * [Mutações](#mutações) 39 | * [Strings](#strings) 40 | * [Exceções](#exceções) 41 | * [Macros](#macros) 42 | * [Comentários](#comentários) 43 | * [Anotações de Comentários](#anotações-de-comentários) 44 | * [Existencial](#existencial) 45 | * [Ferramentas](#ferramentas) 46 | * [Testando](#testando) 47 | * [Documentação](#documentação) 48 | * [Organização das bibliotecas](#library-organization) 49 | 50 | 51 | ## Disposição do código & Organização 52 | 53 | > Nearly everybody is convinced that every style but their own is 54 | > ugly and unreadable. Leave out the "but their own" and they're 55 | > probably right...
56 | > -- Jerry Coffin (on indentation) 57 | 58 | * 59 | Use **espaços** na identação. Não use tab. 60 | [[link](#spaces)] 61 | 62 | * 63 | Use 2 spaces to indent the bodies of 64 | forms that have body parameters. This covers all `def` forms, special 65 | forms and macros that introduce local bindings (e.g. `loop`, `let`, 66 | `when-let`) and many macros like `when`, `cond`, `as->`, `cond->`, `case`, 67 | `with-*`, etc. 68 | [[link](#body-indentation)] 69 | 70 | 71 | ```Clojure 72 | ;; bom 73 | (when alguma-coisa 74 | (outra-coisa)) 75 | 76 | (with-out-str 77 | (println "Oĺa, ") 78 | (println "mundo!")) 79 | 80 | ;; ruim - quatro espaços 81 | (when alguma-coisa 82 | (outra-coisa)) 83 | 84 | ;; ruim - um espaço 85 | (with-out-str 86 | (println "Oĺá, ") 87 | (println "mundo!")) 88 | ``` 89 | 90 | * 91 | Alinhar verticalmente argumentos da função (macro) distribuída em várias linhas. 92 | [[link](#vertically-align-fn-args)] 93 | 94 | ```Clojure 95 | ;; bom 96 | (filter even? 97 | (range 1 10)) 98 | 99 | ;; ruim 100 | (filter even? 101 | (range 1 10)) 102 | ``` 103 | 104 | * 105 | Use um único espaço para os argumentos da função quando não há argumentos na mesma linha que o nome da função. 106 | [[link](#one-space-indent)] 107 | 108 | ```Clojure 109 | ;; bom 110 | (filter 111 | even? 112 | (range 1 10)) 113 | 114 | (or 115 | ala 116 | bala 117 | portokala) 118 | 119 | ;; ruim - dois espaços 120 | (filter 121 | even? 122 | (range 1 10)) 123 | 124 | (or 125 | ala 126 | bala 127 | portokala) 128 | ``` 129 | 130 | * 131 | Alinhar verticalmente ligações `let` e keyword maps. 132 | [[link](#vertically-align-let-and-map)] 133 | 134 | ```Clojure 135 | ;; bom 136 | (let [coisa1 "alguma coisa" 137 | coisa2 "outra coisa"] 138 | {:coisa1 coisa1 139 | :coisa2 coisa2}) 140 | 141 | ;; ruim 142 | (let [coisa1 "alguma coisa" 143 | coisa2 "outra coisa"] 144 | {:coisa1 coisa1 145 | :coisa2 coisa2}) 146 | ``` 147 | 148 | * 149 | Opcionalmente, omita a nova linha entre o nome da função e o vetor de 150 | argumento para `defn` quando não há docstring. 151 | [[link](#optional-new-line-after-fn-name)] 152 | 153 | ```Clojure 154 | ;; bom 155 | (defn foo 156 | [x] 157 | (bar x)) 158 | 159 | ;; bom 160 | (defn foo [x] 161 | (bar x)) 162 | 163 | ;; ruim 164 | (defn foo 165 | [x] (bar x)) 166 | ``` 167 | 168 | * 169 | Coloque a `dispatch-val` de um método múltiplo na mesma linha que o nome da 170 | função. 171 | [[link](#multimethod-dispatch-val-placement)] 172 | 173 | 174 | ```Clojure 175 | ;; bom 176 | (defmethod foo :bar [x] (baz x)) 177 | 178 | (defmethod foo :bar 179 | [x] 180 | (baz x)) 181 | 182 | ;; ruim 183 | (defmethod foo 184 | :bar 185 | [x] 186 | (baz x)) 187 | 188 | (defmethod foo 189 | :bar [x] 190 | (baz x)) 191 | ``` 192 | 193 | * 194 | Opcionalmente, omita a nova linha entre o vetor de argumento e um corpo de 195 | função curto. 196 | [[link](#oneline-short-fn)] 197 | 198 | ```Clojure 199 | ;; bom 200 | (defn foo [x] 201 | (bar x)) 202 | 203 | ;; bom for a small function body 204 | (defn foo [x] (bar x)) 205 | 206 | ;; bom for multi-arity functions 207 | (defn foo 208 | ([x] (bar x)) 209 | ([x y] 210 | (if (predicate? x) 211 | (bar x) 212 | (baz x)))) 213 | 214 | ;; ruim 215 | (defn foo 216 | [x] (if (predicate? x) 217 | (bar x) 218 | (baz x))) 219 | ``` 220 | 221 | * 222 | Indente cada forma de aridade de uma definição de função alinhada verticalmente 223 | com seus parâmetros.[[link](#multiple-arity-indentation)] 224 | 225 | ```Clojure 226 | ;; bom 227 | (defn foo 228 | "I have two arities." 229 | ([x] 230 | (foo x 1)) 231 | ([x y] 232 | (+ x y))) 233 | 234 | ;; ruim - extra indentation 235 | (defn foo 236 | "I have two arities." 237 | ([x] 238 | (foo x 1)) 239 | ([x y] 240 | (+ x y))) 241 | ``` 242 | 243 | * Sort the arities of a function 244 | from fewest to most arguments. The common case of multi-arity 245 | functions is that some K arguments fully specifies the function's 246 | behavior, and that arities N < K partially apply the K arity, and 247 | arities N > K provide a fold of the K arity over varargs. 248 | [[link](#multiple-arity-order)] 249 | 250 | ```Clojure 251 | ;; bom - it's easy to scan for the nth arity 252 | (defn foo 253 | "I have two arities." 254 | ([x] 255 | (foo x 1)) 256 | ([x y] 257 | (+ x y))) 258 | 259 | ;; okay - the other arities are applications of the two-arity 260 | (defn foo 261 | "I have two arities." 262 | ([x y] 263 | (+ x y)) 264 | ([x] 265 | (foo x 1)) 266 | ([x y z & more] 267 | (reduce foo (foo x (foo y z)) more))) 268 | 269 | ;; ruim - unordered for no apparent reason 270 | (defn foo 271 | ([x] 1) 272 | ([x y z] (foo x (foo y z))) 273 | ([x y] (+ x y)) 274 | ([w x y z & more] (reduce foo (foo w (foo x (foo y z))) more))) 275 | ``` 276 | 277 | * 278 | Use Unix-style line endings. (*BSD/Solaris/Linux/OSX users are 279 | covered by default, Windows users have to be extra careful.) 280 | [[link](#crlf)] 281 | 282 | * If you're using Git you might want to add the following 283 | configuration setting to protect your project from Windows line 284 | endings creeping in: 285 | 286 | ``` 287 | bash$ git config --global core.autocrlf true 288 | ``` 289 | 290 | * 291 | If any text precedes an opening bracket(`(`, `{` and 292 | `[`) or follows a closing bracket(`)`, `}` and `]`), separate that 293 | text from that bracket with a space. Conversely, leave no space after 294 | an opening bracket and before following text, or after preceding text 295 | and before a closing bracket. 296 | [[link](#bracket-spacing)] 297 | 298 | ```Clojure 299 | ;; bom 300 | (foo (bar baz) quux) 301 | 302 | ;; ruim 303 | (foo(bar baz)quux) 304 | (foo ( bar baz ) quux) 305 | ``` 306 | 307 | > Syntactic sugar causes semicolon cancer.
308 | > -- Alan Perlis 309 | 310 | * 311 | Don't use commas between the elements of sequential collection literals. 312 | [[link](#no-commas-for-seq-literals)] 313 | 314 | ```Clojure 315 | ;; bom 316 | [1 2 3] 317 | (1 2 3) 318 | 319 | ;; ruim 320 | [1, 2, 3] 321 | (1, 2, 3) 322 | ``` 323 | 324 | * 325 | Consider enhancing the readability of map literals via judicious use 326 | of commas and line breaks. 327 | [[link](#opt-commas-in-map-literals)] 328 | 329 | ```Clojure 330 | ;; bom 331 | {:name "Bruce Wayne" :alter-ego "Batman"} 332 | 333 | ;; bom and arguably a bit more readable 334 | {:name "Bruce Wayne" 335 | :alter-ego "Batman"} 336 | 337 | ;; bom and arguably more compact 338 | {:name "Bruce Wayne", :alter-ego "Batman"} 339 | ``` 340 | 341 | * 342 | Place all trailing parentheses on a single line instead of distinct lines. 343 | [[link](#gather-trailing-parens)] 344 | 345 | ```Clojure 346 | ;; bom; single line 347 | (when something 348 | (something-else)) 349 | 350 | ;; ruim; distinct lines 351 | (when something 352 | (something-else) 353 | ) 354 | ``` 355 | 356 | * 357 | Use empty lines between top-level forms. 358 | [[link](#empty-lines-between-top-level-forms)] 359 | 360 | ```Clojure 361 | ;; bom 362 | (def x ...) 363 | 364 | (defn foo ...) 365 | 366 | ;; ruim 367 | (def x ...) 368 | (defn foo ...) 369 | ``` 370 | 371 | An exception to the rule is the grouping of related `def`s together. 372 | 373 | ```Clojure 374 | ;; bom 375 | (def min-rows 10) 376 | (def max-rows 20) 377 | (def min-cols 15) 378 | (def max-cols 30) 379 | ``` 380 | 381 | * 382 | Do not place blank lines in the middle of a function or 383 | macro definition. An exception can be made to indicate grouping of 384 | pairwise constructs as found in e.g. `let` and `cond`. 385 | [[link](#no-blank-lines-within-def-forms)] 386 | 387 | * 388 | Where feasible, avoid making lines longer than 80 characters. 389 | [[link](#80-character-limits)] 390 | 391 | * 392 | Avoid trailing whitespace. 393 | [[link](#no-trailing-whitespace)] 394 | 395 | * 396 | Use one file per namespace. 397 | [[link](#one-file-per-namespace)] 398 | 399 | * 400 | Start every namespace with a comprehensive `ns` form, comprised of 401 | `refer`s, `require`s, and `import`s, conventionally in that order. 402 | [[link](#comprehensive-ns-declaration)] 403 | 404 | ```Clojure 405 | (ns examples.ns 406 | (:refer-clojure :exclude [next replace remove]) 407 | (:require [clojure.string :as s :refer [blank?]] 408 | [clojure.set :as set] 409 | [clojure.java.shell :as sh]) 410 | (:import java.util.Date 411 | java.text.SimpleDateFormat 412 | [java.util.concurrent Executors 413 | LinkedBlockingQueue])) 414 | ``` 415 | 416 | * 417 | In the `ns` form prefer `:require :as` over `:require :refer` over `:require 418 | :refer :all`. Prefer `:require` over `:use`; the latter form should be 419 | considered deprecated for new code. 420 | [[link](#prefer-require-over-use)] 421 | 422 | ```Clojure 423 | ;; bom 424 | (ns examples.ns 425 | (:require [clojure.zip :as zip])) 426 | 427 | ;; bom 428 | (ns examples.ns 429 | (:require [clojure.zip :refer [lefts rights]])) 430 | 431 | ;; acceptable as warranted 432 | (ns examples.ns 433 | (:require [clojure.zip :refer :all])) 434 | 435 | ;; ruim 436 | (ns examples.ns 437 | (:use clojure.zip)) 438 | ``` 439 | 440 | * 441 | Avoid single-segment namespaces. 442 | [[link](#no-single-segment-namespaces)] 443 | 444 | ```Clojure 445 | ;; bom 446 | (ns example.ns) 447 | 448 | ;; ruim 449 | (ns example) 450 | ``` 451 | 452 | * 453 | Avoid the use of overly long namespaces (i.e., more than 5 segments). 454 | [[link](#namespaces-with-5-segments-max)] 455 | 456 | * 457 | Avoid functions longer than 10 LOC (lines of code). Ideally, most 458 | functions will be shorter than 5 LOC. 459 | [[link](#10-loc-per-fn-limit)] 460 | 461 | * 462 | Avoid parameter lists with more than three or four positional parameters. 463 | [[link](#4-positional-fn-params-limit)] 464 | 465 | * 466 | Avoid forward references. They are occasionally necessary, but such occasions 467 | are rare in practice. 468 | [[link](#forward-references)] 469 | 470 | ## Sintaxe 471 | 472 | * 473 | Evite o uso de funções de manipulação de namespace como `require` e 474 | `refer`. Elas são desnecessárias fora do ambiente REPL. 475 | [[link](#ns-fns-only-in-repl)] 476 | 477 | * 478 | Use `declare` para habilitar referências futuras quando elas forem 479 | necessárias. 480 | [[link](#declare)] 481 | 482 | * 483 | Prefira funções de alta ordem como `map` no lugar de `loop/recur`. 484 | [[link](#higher-order-fns)] 485 | 486 | * 487 | Prefira funções de pre e pos condições para fazer checagens 488 | dentro do corpo de uma função. 489 | [[link](#pre-post-conditions)] 490 | 491 | ```Clojure 492 | ;; bom 493 | (defn foo [x] 494 | {:pre [(pos? x)]} 495 | (bar x)) 496 | 497 | ;; ruim 498 | (defn foo [x] 499 | (if (pos? x) 500 | (bar x) 501 | (throw (IllegalArgumentException. "x deve ser um número positivo!"))) 502 | ``` 503 | 504 | * 505 | Não defina variáveis dentro de funções. 506 | [[link](#dont-def-vars-inside-fns)] 507 | 508 | ```Clojure 509 | ;; muito ruim 510 | (defn foo [] 511 | (def x 5) 512 | ...) 513 | ``` 514 | 515 | * 516 | Não sobrescreva nomes `clojure.core` com atribuições locais. 517 | [[link](#dont-shadow-clojure-core)] 518 | 519 | ```Clojure 520 | ;; ruim - você é forçado a usar clojure.core/map com todo namespace 521 | (defn foo [map] 522 | ...) 523 | ``` 524 | 525 | * 526 | Use `alter-var-root` no lugar de `def` para alterar o valor de variáveis. 527 | [[link]](#alter-var) 528 | 529 | ```Clojure 530 | ;; bom 531 | (def variável 1) ; o valor de coisa agora é 1 532 | ; faz algo com variável 533 | (alter-var-root #'variável (constantly nil)) ; valor de variável agora é nil 534 | 535 | ;; ruim 536 | (def variável 1) 537 | ; faz algo com variável 538 | (def variável nil) 539 | ; valor de variável é nil agora 540 | ``` 541 | 542 | * 543 | Use `seq` como uma condição terminal para verificar quando uma sequência 544 | é vazia (essa técnica é as vezes chamada de *nil punning*). 545 | [[link](#nil-punning)] 546 | 547 | ```Clojure 548 | ;; bom 549 | (defn print-seq [s] 550 | (when (seq s) 551 | (prn (first s)) 552 | (recur (rest s)))) 553 | 554 | ;; ruim 555 | (defn print-seq [s] 556 | (when-not (empty? s) 557 | (prn (first s)) 558 | (recur (rest s)))) 559 | ``` 560 | 561 | * 562 | Prefira `vec` no lugar de `into` que precisar converter uma sequância em um vetor. 563 | [[link](#to-vector)] 564 | 565 | ```Clojure 566 | ;; bom 567 | (vec uma-seq) 568 | 569 | ;; ruim 570 | (into [] uma-seq) 571 | ``` 572 | 573 | * 574 | Use `when` instead of `(if ... (do ...))`. 575 | [[link](#when-instead-of-single-branch-if)] 576 | 577 | ```Clojure 578 | ;; bom 579 | (when pred 580 | (foo) 581 | (bar)) 582 | 583 | ;; ruim 584 | (if pred 585 | (do 586 | (foo) 587 | (bar))) 588 | ``` 589 | 590 | * 591 | Use `if-let` no lugar de `let` + `if`. 592 | [[link](#if-let)] 593 | 594 | ```Clojure 595 | ;; bom 596 | (if-let [resultado (foo x)] 597 | (algo-com resultado) 598 | (oura-coisa)) 599 | 600 | ;; ruim 601 | (let [resultado (foo x)] 602 | (if resultado 603 | (algo-com resultado) 604 | (outra-coisa))) 605 | ``` 606 | 607 | * 608 | Use `when-let` no lugar de `let` + `when`. 609 | [[link](#when-let)] 610 | 611 | ```Clojure 612 | ;; bom 613 | (when-let [resultado (foo x)] 614 | (faz-algo-com resultado) 615 | (faz-algo-mais-com resultado)) 616 | 617 | ;; ruim 618 | (let [resultado (foo x)] 619 | (when resultado 620 | (faz-algo-com resultado) 621 | (faz-algo-mais-com resultado))) 622 | ``` 623 | 624 | * 625 | Use `if-not` no lugar de `(if (not ...) ...)`. 626 | [[link](#if-not)] 627 | 628 | ```Clojure 629 | ;; bom 630 | (if-not pred 631 | (foo)) 632 | 633 | ;; ruim 634 | (if (not pred) 635 | (foo)) 636 | ``` 637 | 638 | * 639 | Use `when-not` no lugar de `(when (not ...) ...)`. 640 | [[link](#when-not)] 641 | 642 | ```Clojure 643 | ;; bom 644 | (when-not pred 645 | (foo) 646 | (bar)) 647 | 648 | ;; ruim 649 | (when (not pred) 650 | (foo) 651 | (bar)) 652 | ``` 653 | 654 | * 655 | Use `when-not` instead of `(if-not ... (do ...))`. 656 | [[link](#when-not-instead-of-single-branch-if-not)] 657 | 658 | ```Clojure 659 | ;; bom 660 | (when-not pred 661 | (foo) 662 | (bar)) 663 | 664 | ;; ruim 665 | (if-not pred 666 | (do 667 | (foo) 668 | (bar))) 669 | ``` 670 | 671 | * 672 | Use `not=` no lugar de `(not (= ...))`. 673 | [[link](#not-equal)] 674 | 675 | ```Clojure 676 | ;; bom 677 | (not= foo bar) 678 | 679 | ;; ruim 680 | (not (= foo bar)) 681 | ``` 682 | 683 | * 684 | Use `printf` no lugar de `(print (format ...))`. 685 | [[link](#printf)] 686 | 687 | ```Clojure 688 | ;; bom 689 | (printf "Olá, %s!\n" nome) 690 | 691 | ;; ok 692 | (println (format "Olá, %s!" nome)) 693 | ``` 694 | 695 | * 696 | Quando fizer comparações, tenha em mente que as funções Clojure `<`, 697 | `>`, etc. aceitam um número variável de argumentos. 698 | [[link](#multiple-arity-of-gt-and-ls-fns)] 699 | 700 | ```Clojure 701 | ;; bom 702 | (< 5 x 10) 703 | 704 | ;; ruim 705 | (and (> x 5) (< x 10)) 706 | ``` 707 | 708 | * 709 | Prefira `%` no lugar de `%1` nos argumentos de funções com apenas um parâmetro. 710 | [[link](#single-param-fn-literal)] 711 | 712 | ```Clojure 713 | ;; bom 714 | #(Math/round %) 715 | 716 | ;; ruim 717 | #(Math/round %1) 718 | ``` 719 | 720 | * 721 | Prefira `%1` no lugar de `%` nos argumentos de funções com mais de um parâmetro. 722 | [[link](#multiple-params-fn-literal)] 723 | 724 | ```Clojure 725 | ;; bom 726 | #(Math/pow %1 %2) 727 | 728 | ;; ruim 729 | #(Math/pow % %2) 730 | ``` 731 | 732 | * 733 | Não envolva funções com funções anônimas sem necessidade. 734 | [[link](#no-useless-anonymous-fns)] 735 | 736 | ```Clojure 737 | ;; bom 738 | (filter even? (range 1 10)) 739 | 740 | ;; ruim 741 | (filter #(even? %) (range 1 10)) 742 | ``` 743 | 744 | * 745 | Não use literais de uma função se o corpo da função vai consistir em 746 | mais de uma chamada. 747 | [[link](#no-multiple-forms-fn-literals)] 748 | 749 | ```Clojure 750 | ;; bom 751 | (fn [x] 752 | (println x) 753 | (* x 2)) 754 | 755 | ;; ruim (você precisa explicitamente de uma chamada do) 756 | #(do (println %) 757 | (* % 2)) 758 | ``` 759 | 760 | * 761 | Prefira o uso de `complement` no lugar de uma função anônima. 762 | [[link](#complement)] 763 | 764 | ```Clojure 765 | ;; bom 766 | (filter (complement some-pred?) coll) 767 | 768 | ;; ruim 769 | (filter #(not (some-pred? %)) coll) 770 | ``` 771 | 772 | Essa regra deve obviamente ser ignorada se já existir uma função que 773 | faz o mesmo que usar o complemento (e.g. `even?` e `odd?`). 774 | 775 | * 776 | Usar `comp` pode deixar o código mais simples. 777 | [[link](#comp)] 778 | 779 | ```Clojure 780 | ;; Assumindo `(:require [clojure.string :as str])`... 781 | 782 | ;; bom 783 | (map #(str/capitalize (str/trim %)) ["top " " test "]) 784 | 785 | ;; melhor 786 | (map (comp str/capitalize str/trim) ["top " " test "]) 787 | ``` 788 | 789 | * 790 | Usar `partial` pode deixar o código mais simples. 791 | [[link](#partial)] 792 | 793 | ```Clojure 794 | ;; bom 795 | (map #(+ 5 %) (range 1 10)) 796 | 797 | ;; (dicutivelmente) melhor 798 | (map (partial + 5) (range 1 10)) 799 | ``` 800 | 801 | * 802 | Prefira o uso de threading macros `->` (thread-first) e `->>` 803 | (thread-last) no lugar de aninhamentos exaustivos. 804 | [[link](#threading-macros)] 805 | 806 | ```Clojure 807 | ;; bom 808 | (-> [1 2 3] 809 | reverse 810 | (conj 4) 811 | prn) 812 | 813 | ;; não muito bom 814 | (prn (conj (reverse [1 2 3]) 815 | 4)) 816 | 817 | ;; bom 818 | (->> (range 1 10) 819 | (filter even?) 820 | (map (partial * 2))) 821 | 822 | ;; não muito bom 823 | (map (partial * 2) 824 | (filter even? (range 1 10))) 825 | ``` 826 | 827 | * 828 | Use `:else` como um teste de experessão catch-all em `cond`. 829 | [[link](#else-keyword-in-cond)] 830 | 831 | ```Clojure 832 | ;; bom 833 | (cond 834 | (neg? n) "negativo" 835 | (pos? n) "positivo" 836 | :else "zero") 837 | 838 | ;; ruim 839 | (cond 840 | (neg? n) "negativo" 841 | (pos? n) "positivo" 842 | true "zero") 843 | ``` 844 | 845 | * 846 | Prefira `condp` no lugar de `cond` quando o predicado e expressão não mudarem. 847 | [[link](#condp)] 848 | 849 | ```Clojure 850 | ;; bom 851 | (cond 852 | (= x 10) :dez 853 | (= x 20) :vinte 854 | (= x 30) :trinta 855 | :else :nao-sei) 856 | 857 | ;; muito melhor 858 | (condp = x 859 | 10 :dez 860 | 20 :vinte 861 | 30 :trinta 862 | :nao-sei) 863 | ``` 864 | 865 | * 866 | Prefira `case` no lugar de `cond` ou `condp` quando expressões de checagens são 867 | constantes de tempo de compilação. 868 | [[link](#case)] 869 | 870 | ```Clojure 871 | ;; bom 872 | (cond 873 | (= x 10) :dez 874 | (= x 20) :vinte 875 | (= x 30) :trinta 876 | :else :nao-sei) 877 | 878 | ;; melhor que anterior 879 | (condp = x 880 | 10 :dez 881 | 20 :vinte 882 | 30 :trinta 883 | :nao-sei) 884 | 885 | ;; melhor caso 886 | (case x 887 | 10 :dez 888 | 20 :vinte 889 | 30 :trinta 890 | :nao-sei) 891 | ``` 892 | 893 | * 894 | Use formas curtas no `cond` e similares. Se não for possível dê dicar visuais 895 | para as assosiações com comentário ou linhas em branco. 896 | [[link](#shor-forms-in-cond)] 897 | 898 | ```Clojure 899 | ;; bom 900 | (cond 901 | (test1) (acao-1) 902 | (test2) (acao-2) 903 | :else (action-padrao)) 904 | 905 | ;; ok 906 | (cond 907 | ;; test caso 1 908 | (test1) 909 | (funcao-com-nome-longo-que-requer-uma-nova-linha 910 | (sub-forma-complicada 911 | (-> 'que-abrange multiplas-linhas))) 912 | 913 | ;; test caso 2 914 | (test2) 915 | (outra-funcao-de-nome-grande 916 | (outra-sub-forma 917 | (-> 'que-abrange multiplas-linhas))) 918 | 919 | :else 920 | (o-caso-padrao 921 | (que-tambem-abrange 'multiplas 922 | 'linhas))) 923 | ``` 924 | 925 | * 926 | Use um `set` como predicado quando apropriado. 927 | [[link](#set-as-predicate)] 928 | 929 | ```Clojure 930 | ;; bom 931 | (remove #{1} [0 1 2 3 4 5]) 932 | 933 | ;; ruim 934 | (remove #(= % 1) [0 1 2 3 4 5]) 935 | 936 | ;; bom 937 | (count (filter #{\a \e \i \o \u} "mary had a little lamb")) 938 | 939 | ;; ruim 940 | (count (filter #(or (= % \a) 941 | (= % \e) 942 | (= % \i) 943 | (= % \o) 944 | (= % \u)) 945 | "mary had a little lamb")) 946 | ``` 947 | 948 | * 949 | Use `(inc x)` & `(dec x)` no lugar de `(+ x 1)` e `(- x 1)`. 950 | [[link](#inc-and-dec)] 951 | 952 | * 953 | Use `(pos? x)`, `(neg? x)` & `(zero? x)` no lugar de `(> x 0)`, 954 | `(< x 0)` & `(= x 0)`. 955 | [[link](#pos-and-neg)] 956 | 957 | * 958 | Use `list*` no lugar de uma serie de chamadas `cons` aninhadas. 959 | [[link](#list-star-instead-of-nested-cons)] 960 | 961 | ```Clojure 962 | ;; bom 963 | (list* 1 2 3 [4 5]) 964 | 965 | ;; ruim 966 | (cons 1 (cons 2 (cons 3 [4 5]))) 967 | ``` 968 | 969 | * 970 | Use os formulários de interoperabilidade Java. 971 | [[link](#sugared-java-interop)] 972 | 973 | ```Clojure 974 | ;;; criação do objeto 975 | ;; bom 976 | (java.util.ArrayList. 100) 977 | 978 | ;; ruim 979 | (new java.util.ArrayList 100) 980 | 981 | ;;; chamada de método estático 982 | ;; bom 983 | (Math/pow 2 10) 984 | 985 | ;; ruim 986 | (. Math pow 2 10) 987 | 988 | ;;; chamada de instância de método 989 | ;; bom 990 | (.substring "ola" 1 3) 991 | 992 | ;; ruim 993 | (. "ola" substring 1 3) 994 | 995 | ;;; acesso a campo estático 996 | ;; bom 997 | Integer/MAX_VALUE 998 | 999 | ;; ruim 1000 | (. Integer MAX_VALUE) 1001 | 1002 | ;;; acesso a instância de campo 1003 | ;; bom 1004 | (.umCampo um-objeto) 1005 | 1006 | ;; ruim 1007 | (. um-objeto umObjeto) 1008 | ``` 1009 | 1010 | * 1011 | Use a notação compacta de metadado para metadados de contém apenas 1012 | slots em que as keys são keywords e o valor é booleano `true`. 1013 | [[link](#compact-metadata-notation-for-true-flags)] 1014 | 1015 | ```Clojure 1016 | ;; bom 1017 | (def ^:private a 5) 1018 | 1019 | ;; ruim 1020 | (def ^{:private true} a 5) 1021 | ``` 1022 | 1023 | * 1024 | Denote partes privadas do seu código. 1025 | [[link](#private)] 1026 | 1027 | ```Clojure 1028 | ;; bom 1029 | (defn- funcao-privada [] ...) 1030 | 1031 | (def ^:private variavel-privada ...) 1032 | 1033 | ;; ruim 1034 | (defn funcao-privda [] ...) ; Não é uma função privada 1035 | 1036 | (defn ^:private funcao-privada [] ...) ; muito verbosa 1037 | 1038 | (def variavel-privada ...) ; Não é privada 1039 | ``` 1040 | 1041 | * 1042 | Para acessar uma variável privada (e.g. para testes), use a notação `@#'some.ns/var`. 1043 | [[link](#access-private-var)] 1044 | 1045 | * 1046 | Tenha cuidado ao que você associa seu metadado exatamente. 1047 | [[link](#attach-metadata-carefully)] 1048 | 1049 | ```Clojure 1050 | ;; nós associamos o metadado a variável referenciada por `a` 1051 | (def ^:private a {}) 1052 | (meta a) ;=> nil 1053 | (meta #'a) ;=> {:private true} 1054 | 1055 | ;; nós associamos o metadado ao valor vazio do hash-map 1056 | (def a ^:private {}) 1057 | (meta a) ;=> {:private true} 1058 | (meta #'a) ;=> nil 1059 | ``` 1060 | 1061 | ## Nomenclaturas 1062 | 1063 | > As únicas reais dificuldades em programação são invalidação de cache e 1064 | > nomear coisas.
1065 | > -- Phil Karlton 1066 | 1067 | * 1068 | Ao nomear namespaces escolha entre os dois seguintes schemas: 1069 | [[link](#ns-naming-schemas)] 1070 | 1071 | * `project.module` 1072 | * `organization.project.module` 1073 | 1074 | * 1075 | Use `lisp-case` em segmentos de namespace compostos(e.g. `bruce.project-euler`) 1076 | [[link](#lisp-case-ns)] 1077 | 1078 | * 1079 | Use `lisp-case` em funções e nomes de variáveis. 1080 | [[link](#lisp-case)] 1081 | 1082 | ```Clojure 1083 | ;; bom 1084 | (def uma-var ...) 1085 | (defn uma-fun ...) 1086 | 1087 | ;; ruim 1088 | (def umaVar ...) 1089 | (defn umafun ...) 1090 | (def uma_fun ...) 1091 | ``` 1092 | 1093 | * 1094 | Use `CamelCase` para protocolos, registros, estruturas e tipos. (Mantenha 1095 |    acrônimos como HTTP, RFC, XML em maiúsculo.) 1096 | [[link](#CamelCase-for-protocols-records-structs-and-types)] 1097 | 1098 | * 1099 | Os nomes dos métodos predicados (métodos que retornam um valor booleano) 1100 |    devem terminar em um ponto de interrogação 1101 | (e.g., `impar?`). 1102 | [[link](#pred-with-question-mark)] 1103 | 1104 | ```Clojure 1105 | ;; bom 1106 | (defn palindrome? ...) 1107 | 1108 | ;; ruim 1109 | (defn palindrome-p ...) ; estilo Common Lisp 1110 | (defn is-palindrome ...) ; estilo Java 1111 | ``` 1112 | 1113 | * 1114 | Os nomes de funções/macros que não são "safe" em transações STM 1115 | devem terminar com uma ponto de exclamação (e.g. `reset!`). 1116 | [[link](#changing-state-fns-with-exclamation-mark)] 1117 | 1118 | * 1119 | Use `->` no lugar de `to` ao nomear funções de conversão. 1120 | [[link](#arrow-instead-of-to)] 1121 | 1122 | ```Clojure 1123 | ;; bom 1124 | (defn f->c ...) 1125 | 1126 | ;; não muito bom 1127 | (defn f-to-c ...) 1128 | ``` 1129 | 1130 | * 1131 | Use `*earmuffs*` para coisas destinatas a rebinding (ou seja, são dinâmicas). 1132 | [[link](#earmuffs-for-dynamic-vars)] 1133 | 1134 | ```Clojure 1135 | ;; bom 1136 | (def ^:dynamic *a* 10) 1137 | 1138 | ;; ruim 1139 | (def ^:dynamic a 10) 1140 | ``` 1141 | 1142 | * 1143 | Não use notações especiais para constantes; tudo é constante 1144 | a não ser que seja especificado do contrário. 1145 | [[link](#dont-flag-constants)] 1146 | 1147 | * 1148 | Use `_` para destructuring e nomes formais para argumentos que terão 1149 | seus valores ignorado pelo código em mãos. 1150 | [[link](#underscore-for-unused-bindings)] 1151 | 1152 | ```Clojure 1153 | ;; bom 1154 | (let [[a b _ c] [1 2 3 4]] 1155 | (println a b c)) 1156 | 1157 | (dotimes [_ 3] 1158 | (println "Hello!")) 1159 | 1160 | ;; ruim 1161 | (let [[a b c d] [1 2 3 4]] 1162 | (println a b d)) 1163 | 1164 | (dotimes [i 3] 1165 | (println "Hello!")) 1166 | ``` 1167 | 1168 | * 1169 | Siga o exemplo `clojure.core`'s para nomes idiomáticos como `pred` e `coll`. 1170 | [[link](#idiomatic-names)] 1171 | 1172 | * em funções: 1173 | * `f`, `g`, `h` - input da função 1174 | * `n` - input inteiro, normalmente tamanho 1175 | * `index`, `i` - index inteiro 1176 | * `x`, `y` - números 1177 | * `xs` - sequência 1178 | * `m` - map 1179 | * `s` - input string 1180 | * `re` - expressão regular 1181 | * `coll` - uma coleção 1182 | * `pred` - um fechamento de predicado 1183 | * `& more` - input variante 1184 | * `xf` - xform, um transducer 1185 | * em macros: 1186 | * `expr` - uma expressão 1187 | * `body` - o corpo de uma macro 1188 | * `binding` - um vetor binding de uma macro 1189 | 1190 | ## Collections 1191 | 1192 | > É melhor ter 100 funções operando em uma estrutura de dados 1193 | > do que ter 10 funções operando em 10 estrutura de dados.
1194 | > -- Alan J. Perlis 1195 | 1196 | * 1197 | Evite o uso de listas para armazenamento genérico de dados (a menos que uma seja 1198 | exatamente o que você precisa). 1199 | [[link](#avoid-lists)] 1200 | 1201 | * 1202 | Prefira o uso de keywords para hash keys. 1203 | [[link](#keywords-for-hash-keys)] 1204 | 1205 | ```Clojure 1206 | ;; bom 1207 | {:nome "Bruce" :idade 30} 1208 | 1209 | ;; ruim 1210 | {"nome" "Bruce" "idade" 30} 1211 | ``` 1212 | 1213 | * 1214 | Prefira o uso da sintaxe da coleção literal quando aplicável. No entanto, ao 1215 | definir conjuntos, apenas use a sintaxe literal quando os valores forem constantes 1216 | de tempo de compilação. 1217 | [[link](#literal-col-syntax)] 1218 | 1219 | ```Clojure 1220 | ;; bom 1221 | [1 2 3] 1222 | #{1 2 3} 1223 | (hash-set (func1) (func2)) ; valores determinados em tempo de execução 1224 | 1225 | ;; ruim 1226 | (vector 1 2 3) 1227 | (hash-set 1 2 3) 1228 | #{(func1) (func2)} ; irá lançar exceção de tempo de execução se (func1) = (func2) 1229 | ``` 1230 | 1231 | * 1232 | Evite acessar os membros da coleção por índice sempre que possível. 1233 | [[link](#avoid-index-based-coll-access)] 1234 | 1235 | * 1236 | Prefira o uso de keywords como funções para recuperar valores de mapas, 1237 | quando aplicável. 1238 | [[link](#keywords-as-fn-to-get-map-values)] 1239 | 1240 | ```Clojure 1241 | (def m {:nome "Bruce" :idade 30}) 1242 | 1243 | ;; bom 1244 | (:nome m) 1245 | 1246 | ;; mais detalhado que o necessário 1247 | (get m :nome) 1248 | 1249 | ;; ruim - suscetível a NullPointerException 1250 | (m :nome) 1251 | ``` 1252 | 1253 | * 1254 | Aproveite o fato de que a maioria das coleções são funções de seus elementos. 1255 | [[link](#colls-as-fns)] 1256 | 1257 | ```Clojure 1258 | ;; bom 1259 | (filter #{\a \e \o \i \u} "isso é um teste") 1260 | 1261 | ;; ruim - muito feio para compartilhar 1262 | ``` 1263 | 1264 | * 1265 | Aproveite o fato de que keywords podem ser usadas como funções de uma coleção. 1266 | [[link](#keywords-as-fns)] 1267 | 1268 | ```Clojure 1269 | ((juxt :a :b) {:a "ala" :b "bala"}) 1270 | ``` 1271 | 1272 | * 1273 | Evite o uso de coleções transitórias, exceto em partes críticas de desempenho 1274 | do código. 1275 | [[link](#avoid-transient-colls)] 1276 | 1277 | * 1278 | Evite o uso de Java collections. 1279 | [[link](#avoid-java-colls)] 1280 | 1281 | * 1282 | Evite o uso de arrays de of Java arrays, exceto para cenários de 1283 | interoperabilidade e código de desempenho crítico lidando fortemente com tipos 1284 | primitivos. 1285 | [[link](#avoid-java-arrays)] 1286 | 1287 | ## Mutações 1288 | 1289 | ### Refs 1290 | 1291 | * 1292 | Considere agrupar todas as chamadas I/O com a macro `io!` para evitar surpresas 1293 | desagradáveis se acidentalmente acabar chamando esse código em uma transação. 1294 | [[link](#refs-io-macro)] 1295 | 1296 | * 1297 | Evite o uso de `ref-set` sempre que possível. 1298 | [[link](#refs-avoid-ref-set)] 1299 | 1300 | ```Clojure 1301 | (def r (ref 0)) 1302 | 1303 | ;; bom 1304 | (dosync (alter r + 5)) 1305 | 1306 | ;; ruim 1307 | (dosync (ref-set r 5)) 1308 | ``` 1309 | 1310 | * 1311 | Tente manter o tamanho das transações (a quantidade de trabalho encapsulado nelas) 1312 | o menor possível. 1313 | [[link](#refs-small-transactions)] 1314 | 1315 | * 1316 | Evite que transações de curta e longa duração interajam com a mesma Ref. 1317 | [[link](#refs-avoid-short-long-transactions-with-same-ref)] 1318 | 1319 | ### Agentes 1320 | 1321 | * 1322 | Use `send` somente para ações que são ligadas à CPU e não bloqueiam em I/O 1323 | ou outras threads. 1324 | [[link](#agents-send)] 1325 | 1326 | * 1327 | Use `send-off` para ações que possam bloquear, suspender ou amarrar a thread. 1328 | [[link](#agents-send-off)] 1329 | 1330 | ### Atoms 1331 | 1332 | * 1333 | Evite atualizações de atom dentro de transações STM. 1334 | [[link](#atoms-no-update-within-transactions)] 1335 | 1336 | * 1337 | Tente usar `swap!` no lugar de `reset!` onde for possível. 1338 | [[link](#atoms-prefer-swap-over-reset)] 1339 | 1340 | ```Clojure 1341 | (def a (atom 0)) 1342 | 1343 | ;; bom 1344 | (swap! a + 5) 1345 | 1346 | ;; not as good 1347 | (reset! a 5) 1348 | ``` 1349 | 1350 | ## Strings 1351 | 1352 | * 1353 | Prefira as funções de manipulação de strings do `clojure.string` do que a 1354 | interoperabilidade Java ou escrever sua própria. 1355 | [[link](#prefer-clojure-string-over-interop)] 1356 | 1357 | ```Clojure 1358 | ;; bom 1359 | (clojure.string/upper-case "bruce") 1360 | 1361 | ;; ruim 1362 | (.toUpperCase "bruce") 1363 | ``` 1364 | 1365 | ## Exceções 1366 | 1367 | * 1368 | Reutilize os tipos de exceção existentes. O código idiomático Clojure — 1369 | quando lança uma exceção — lança uma exceção de um tipo padrão (por exemplo, `java.lang.IllegalArgumentException`, `java.lang.UnsupportedOperationException`, `java.lang.IllegalStateException`, `java.io.IOException`). 1370 | [[link](#reuse-existing-exception-types)] 1371 | 1372 | * 1373 | Prefira `with-open` a `finally`. 1374 | [[link](#prefer-with-open-over-finally)] 1375 | 1376 | ## Macros 1377 | 1378 | * 1379 | Não escreva uma macro se uma função faz o mesmo. 1380 | [[link](#dont-write-macro-if-fn-will-do)] 1381 | 1382 | * 1383 | Crie um exemplo de uso de macro primeiro e depois a macro. 1384 | [[link](#write-macro-usage-before-writing-the-macro)] 1385 | 1386 | * 1387 | Quebre as macros complicadas em funções menores sempre que possível. 1388 | [[link](#break-complicated-macros)] 1389 | 1390 | * 1391 | Uma macro geralmente deve fornecer apenas açúcar sintático e o núcleo da macro 1392 | deve ser uma função simples. Isso aumentará a composibilidade. 1393 | [[link](#macros-as-syntactic-sugar)] 1394 | 1395 | * 1396 | Prefira formulários entre aspas de sintaxe a construir listas manualmente. 1397 | [[link](#syntax-quoted-forms)] 1398 | 1399 | ## Comentários 1400 | 1401 | > Um bom código é sua melhor documentação. Quando estiver prestes a adicionar um 1402 | > comentário, pergunte a si mesmo, "Como eu posso melhorar o código de maneira que esse 1403 | > comentário não seja necessário?" Melhore o código e então o documente para deixá-lo 1404 | > ainda mais claro.
1405 | > -- Steve McConnell 1406 | 1407 | * 1408 | Se esforce para tornar seu código o mais auto-documentável possível. 1409 | [[link](#self-documenting-code)] 1410 | 1411 | * 1412 | Escreva comentários de cabeçalho com pelo menos quatro ponto e vírgulas. 1413 | [[link](#four-semicolons-for-heading-comments)] 1414 | 1415 | * 1416 | Escreva comentários top-level com três ponto e vírgulas. 1417 | [[link](#three-semicolons-for-top-level-comments)] 1418 | 1419 | * 1420 | Escreva comentários em um fragmento particular de código antes do fragmento 1421 | e alinhado com o mesmo, utilizando dois ponto e vírgulas. 1422 | [[link](#two-semicolons-for-code-fragment)] 1423 | 1424 | * 1425 | Escreva comentários de margem com um ponto e vírgula. 1426 | [[link](#one-semicolon-for-margin-comments)] 1427 | 1428 | * 1429 | Sempre tenha pelo menos um espaço entre o ponto e vírgula 1430 | e o texto que o segue. 1431 | [[link](#semicolon-space)] 1432 | 1433 | ```Clojure 1434 | ;;;; Frob Grovel 1435 | 1436 | ;;; Esse código tem algumas implicações importantes: 1437 | ;;; 1. Foo. 1438 | ;;; 2. Bar. 1439 | ;;; 3. Baz. 1440 | 1441 | (defn fnord [zarquon] 1442 | ;; Se zob, então veeblefitz. 1443 | (quux zot 1444 | mumble ; Zibblefrotz. 1445 | frotz)) 1446 | ``` 1447 | 1448 | * 1449 | Comentários maiores que uma palavra começam com letra maiúscula e usam 1450 | pontuação. Sentenças separadas com 1451 | [um espaço](http://en.wikipedia.org/wiki/Sentence_spacing). 1452 | [[link](#english-syntax)] 1453 | 1454 | * 1455 | Evite comentários supérfulos. 1456 | [[link](#no-superfluous-comments)] 1457 | 1458 | ```Clojure 1459 | ;; ruim 1460 | (inc counter) ; incrementa contador em um 1461 | ``` 1462 | 1463 | * 1464 | Mantenha os comentários existentes atualizados. Um comentário desatualizado é 1465 | pior que nenhum comentário. 1466 | [[link](#comment-upkeep)] 1467 | 1468 | * 1469 | Prefira o uso do macro leitor `#_` no lugar de um comentário normal quando 1470 | precisar comentar um formulário específico. 1471 | [[link](#dash-underscore-reader-macro)] 1472 | 1473 | ```Clojure 1474 | ;; bom 1475 | (+ foo #_(bar x) delta) 1476 | 1477 | ;; ruim 1478 | (+ foo 1479 | ;; (bar x) 1480 | delta) 1481 | ``` 1482 | 1483 | > Um bom código é como uma boa piada - não precisa de explicação.
1484 | > -- Russ Olsen 1485 | 1486 | * 1487 | Evite escrever comentários para explicar um código ruim. Refatore o código para 1488 | torná-lo auto-explicativo. ("Faça ou não faça. Não há tentativa." --Yoda) 1489 | [[link](#refactor-dont-comment)] 1490 | 1491 | ### Anotações de Comentários 1492 | 1493 | * 1494 | Anotações devem geralmente ser escritas na linha imediatamente acima da linha 1495 | do código de relevância. 1496 | [[link](#annotate-above)] 1497 | 1498 | ```Clojure 1499 | ;; good 1500 | (defn some-fun 1501 | [] 1502 | ;; FIXME: Replace baz with the newer bar. 1503 | (baz)) 1504 | 1505 | ;; bad 1506 | ;; FIXME: Replace baz with the newer bar. 1507 | (defn some-fun 1508 | [] 1509 | (baz)) 1510 | ``` 1511 | 1512 | * 1513 | A palavra-chave de anotação é seguida por dois-pontos e um espaço, depois por 1514 | uma nota descrevendo o problema. 1515 | [[link](#annotate-keywords)] 1516 | 1517 | ```Clojure 1518 | ;; good 1519 | (defn some-fun 1520 | [] 1521 | ;; FIXME: Replace baz with the newer bar. 1522 | (baz)) 1523 | 1524 | ;; bad - no colon after annotation 1525 | (defn some-fun 1526 | [] 1527 | ;; FIXME Replace baz with the newer bar. 1528 | (baz)) 1529 | 1530 | ;; bad - no space after colon 1531 | (defn some-fun 1532 | [] 1533 | ;; FIXME:Replace baz with the newer bar. 1534 | (baz)) 1535 | ``` 1536 | 1537 | * 1538 | Se várias linhas forem necessárias para descrever o problema, as linhas 1539 | subsequentes deverão ser indentadas tanto quanto a primeira. 1540 | [[link](#indent-annotations)] 1541 | 1542 | ```Clojure 1543 | ;; good 1544 | (defn some-fun 1545 | [] 1546 | ;; FIXME: This has crashed occasionally since v1.2.3. It may 1547 | ;; be related to the BarBazUtil upgrade. (xz 13-1-31) 1548 | (baz)) 1549 | 1550 | ;; bad 1551 | (defn some-fun 1552 | [] 1553 | ;; FIXME: This has crashed occasionally since v1.2.3. It may 1554 | ;; be related to the BarBazUtil upgrade. (xz 13-1-31) 1555 | (baz)) 1556 | ``` 1557 | 1558 | * 1559 | Marque a anotação com suas iniciais e uma data para que sua relevância possa 1560 | ser facilmente verificada. 1561 | [[link](#sing-and-date-annotations)] 1562 | 1563 | ```Clojure 1564 | (defn some-fun 1565 | [] 1566 | ;; FIXME: Isso quebra ocasionalmente desde v1.2.3. Isso pode 1567 | ;; estar relacionado a atualização do BarBazUtil. (xz 13-1-31) 1568 | (baz)) 1569 | ``` 1570 | 1571 | * 1572 | Em casos que o problema é tão óbvio que qualquer documentação se tornaria redundante, 1573 | anotações podem ser deixadas no final da linha ofensiva sem anotações. Esse uso 1574 | deve ser a exceção e não a regra. 1575 | [[link](#rare-eol-annotations)] 1576 | 1577 | ```Clojure 1578 | (defn bar 1579 | [] 1580 | (sleep 100)) ; OPTIMIZE 1581 | ``` 1582 | 1583 | * 1584 | Use `TODO` para deixar uma observação de recursos ou funcionalidades ausentes 1585 | que devem ser adicionados posteriormente. 1586 | [[link](#todo)] 1587 | 1588 | * 1589 | Use `FIXME` para deixar uma observação de código quebrado que precisa ser 1590 | corrigido. 1591 | [[link](#fixme)] 1592 | 1593 | * 1594 | Use `OPTIMIZE` para deixar uma observação de código lento ou ineficiente que pode 1595 | causar problemas de desempenho. 1596 | [[link](#optimize)] 1597 | 1598 | * 1599 | Use `HACK` para deixar uma observação de to note "code smells" onde práticas de 1600 | codificação questionáveis foram utilizadas e devem ser refatoradas. 1601 | [[link](#hack)] 1602 | 1603 | * 1604 | Use `REVIEW` para deixar uma observação de qualquer coisa que deva ser analisada 1605 | para confirmar se está funcionando conforme o esperado. Por exemplo: `REVIEW: 1606 | Temos certeza de que é assim que o cliente faz X atualmente?` 1607 | [[link](#review)] 1608 | 1609 | * 1610 | Use outras palavras-chave de anotação personalizadas se parecer apropriado, mas 1611 | certifique-se de documentá-las no `README` do seu projeto ou similar. 1612 | [[link](#document-annotations)] 1613 | 1614 | ## Documentação 1615 | 1616 | Docstrings are the primary way to document Clojure code. Many definition forms 1617 | (e.g. `def`, `defn`, `defmacro`, `ns`) 1618 | support docstrings and usually it's a good idea to make good use of them, regardless 1619 | of whether the var in question is something public or private. 1620 | 1621 | If a definition form doesn't support docstrings directly you can still supply them via 1622 | the `:doc` metadata attribute. 1623 | 1624 | This section outlines some of the common conventions and best 1625 | practices for documenting Clojure code. 1626 | 1627 | 1628 | * 1629 | If a form supports docstrings directly prefer them over using `:doc` metadata: 1630 | [[link](#prefer-docstrings)] 1631 | 1632 | ```clojure 1633 | ;; good 1634 | (defn foo 1635 | "This function doesn't do much." 1636 | [] 1637 | ...) 1638 | 1639 | (ns foo.bar.core 1640 | "That's an awesome library.") 1641 | 1642 | ;; bad 1643 | (defn foo 1644 | ^{:doc "This function doesn't do much."} 1645 | [] 1646 | ...) 1647 | 1648 | (ns ^{:doc "That's an awesome library.") 1649 | foo.bar.core) 1650 | ``` 1651 | 1652 | * 1653 | Let the first line in the doc string be a complete, capitalized 1654 | sentence which concisely describes the var in question. This makes it 1655 | easy for tooling (Clojure editors and IDEs) to display a short a summary of 1656 | the docstring at various places. 1657 | [[link](#docstring-summary)] 1658 | 1659 | ```clojure 1660 | ;; good 1661 | (defn frobnitz 1662 | "This function does a frobnitz. 1663 | It will do gnorwatz to achieve this, but only under certain 1664 | circumstances." 1665 | [] 1666 | ...) 1667 | 1668 | ;; bad 1669 | (defn frobnitz 1670 | "This function does a frobnitz. It will do gnorwatz to 1671 | achieve this, but only under certain circumstances." 1672 | [] 1673 | ...) 1674 | ``` 1675 | 1676 | * 1677 | Document all positional arguments, and wrap them them with backticks 1678 | (\`) so that editors and IDEs can identify them and potentially provide extra 1679 | functionality for them. 1680 | [[link](#document-pos-arguments)] 1681 | 1682 | ```clojure 1683 | ;; good 1684 | (defn watsitz 1685 | "Watsitz takes a `frob` and converts it to a znoot. 1686 | When the `frob` is negative, the znoot becomes angry." 1687 | [frob] 1688 | ...) 1689 | 1690 | ;; bad 1691 | (defn watsitz 1692 | "Watsitz takes a frob and converts it to a znoot. 1693 | When the frob is negative, the znoot becomes angry." 1694 | [frob] 1695 | ...) 1696 | ``` 1697 | 1698 | * 1699 | Wrap any var references in the docstring with \` so that tooling 1700 | can identify them. 1701 | [[link](#document-references)] 1702 | 1703 | ```clojure 1704 | ;; good 1705 | (defn wombat 1706 | "Acts much like `clojure.core/identity` except when it doesn't. 1707 | Takes `x` as an argument and returns that. If it feels like it." 1708 | [x] 1709 | ...) 1710 | 1711 | ;; bad 1712 | (defn wombat 1713 | "Acts much like clojure.core/identity except when it doesn't. 1714 | Takes `x` as an argument and returns that. If it feels like it." 1715 | [x] 1716 | ...) 1717 | ``` 1718 | 1719 | * Docstrings should be comprised from 1720 | proper English sentences - this means every sentences should start 1721 | with an capitalized word and should end with the proper punctuation. Sentences 1722 | should be separated with a single space. 1723 | [[link](#docstring-grammar)] 1724 | 1725 | ```clojure 1726 | ;; good 1727 | (def foo 1728 | "All sentences should end with a period (or maybe an exclamation mark). 1729 | And the period should be followed by a space, unless it's the last sentence.") 1730 | 1731 | ;; bad 1732 | (def foo 1733 | "all sentences should end with a period (or maybe an exclamation mark). 1734 | And the period should be followed by a space, unless it's the last sentence") 1735 | ``` 1736 | 1737 | * 1738 | Indent multi-line docstrings by two spaces. 1739 | [[link](#docstring-indentation)] 1740 | 1741 | ```clojure 1742 | ;; good 1743 | (ns my.ns 1744 | "It is actually possible to document a ns. 1745 | It's a nice place to describe the purpose of the namespace and maybe even 1746 | the overall conventions used. Note how _not_ indenting the doc string makes 1747 | it easier for tooling to display it correctly.") 1748 | 1749 | ;; bad 1750 | (ns my.ns 1751 | "It is actually possible to document a ns. 1752 | It's a nice place to describe the purpose of the namespace and maybe even 1753 | the overall conventions used. Note how _not_ indenting the doc string makes 1754 | it easier for tooling to display it correctly.") 1755 | ``` 1756 | 1757 | * 1758 | Neither start nor end your doc strings with any whitespace. 1759 | [[link](#docstring-leading-trailing-whitespace)] 1760 | 1761 | ```clojure 1762 | ;; good 1763 | (def foo 1764 | "I'm so awesome." 1765 | 42) 1766 | 1767 | ;; bad 1768 | (def silly 1769 | " It's just silly to start a doc string with spaces. 1770 | Just as silly as it is to end it with a bunch of them. " 1771 | 42) 1772 | ``` 1773 | 1774 | * 1775 | When adding a docstring – especially to a function using the above form – take 1776 | care to correctly place the docstring after the function name, not after the 1777 | argument vector. The latter is not invalid syntax and won’t cause an error, 1778 | but includes the string as a form in the function body without attaching it to 1779 | the var as documentation. 1780 | [[link](#docstring-after-fn-name)] 1781 | 1782 | ```Clojure 1783 | ;; good 1784 | (defn foo 1785 | "docstring" 1786 | [x] 1787 | (bar x)) 1788 | 1789 | ;; bad 1790 | (defn foo [x] 1791 | "docstring" 1792 | (bar x)) 1793 | ``` 1794 | 1795 | ## Existencial 1796 | 1797 | * 1798 | Codifique de maneira funcional, usando mutação somente quando faz sentido. 1799 | [[link](#be-functional)] 1800 | 1801 | * 1802 | Seja consistente. Em um mundo ideal, seja consistente com essas diretrizes. 1803 | [[link](#be-consistent)] 1804 | 1805 | * 1806 | Use o senso comum. 1807 | [[link](#common-sense)] 1808 | 1809 | ## Ferramentas 1810 | 1811 | Existem algumas ferramentas criadas pela comunidade Clojure que podem ajudá-lo 1812 | em seu esforço em escrever o código de Clojure idiomático. 1813 | 1814 | * [Slamhound](https://github.com/technomancy/slamhound) é uma ferramenta que 1815 | gerará automaticamente declarações `ns` adequadas a partir do seu código existente. 1816 | 1817 | * [kibit](https://github.com/jonase/kibit) é um analisador de código estático 1818 | para Clojure que usa [core.logic](https://github.com/clojure/core.logic) para 1819 | procurar padrões de código para os quais pode haver uma função ou macro mais idiomático. 1820 | 1821 | ## Testando 1822 | 1823 | * 1824 | Armazene seus testes em um diretório separado, normalmente `test/seuprojeto/` (em 1825 | oposição a `src/seuprojeto/`). Sua ferramenta de compilação é responsável por 1826 | disponibilizá-los nos contextos onde são necessários; a maioria dos modelos 1827 | vai fazer isso automaticamente para você. 1828 | [[link](#test-directory-structure)] 1829 | 1830 | * 1831 | Nomeie seu ns `seuprojeto.algumacoisa-test`, um arquivo que geralmente está em 1832 | `test/seuprojeto/algumacoisa_test.clj` (ou `.cljc`, `cljs`). 1833 | [[link](#test-ns-naming)] 1834 | 1835 | * Ao usar `clojure.test`, defina seus testes 1836 | com `deftest` and nomeie com `algumacoisa-test`. For example: 1837 | 1838 | ```clojure 1839 | ;; bom 1840 | (deftest algumacoisa-test ...) 1841 | 1842 | ;; ruim 1843 | (deftest algumacoisa-tests ...) 1844 | (deftest test-algumacoisa ...) 1845 | (deftest algumacoisa ...) 1846 | ``` 1847 | 1848 | [[link](#test-naming)] 1849 | 1850 | ## Library Organization 1851 | 1852 | * 1853 | If you are publishing libraries to be used by others, make sure to 1854 | follow the [Central Repository 1855 | guidelines](http://central.sonatype.org/pages/choosing-your-coordinates.html) 1856 | for choosing your `groupId` and `artifactId`. This helps to prevent 1857 | name conflicts and facilitates the widest possible use. A good 1858 | example is [Component](https://github.com/stuartsierra/component). 1859 | [[link](#lib-coordinates)] 1860 | 1861 | * 1862 | Avoid unnecessary dependencies. For example, a three-line utility 1863 | function copied into a project is usually better than a dependency 1864 | that drags in hundreds of vars you do not plan to use. 1865 | [[link](#lib-min-dependencies)] 1866 | 1867 | * 1868 | Deliver core functionality and integration points in separate 1869 | artifacts. That way, consumers can consume your library without 1870 | being constrained by your unrelated tooling prefences. For example, 1871 | [Component](https://github.com/stuartsierra/component) provides 1872 | core functionality, and 1873 | [reloaded](https://github.com/stuartsierra/reloaded) provides leiningen 1874 | integration. 1875 | [[link](#lib-core-separate-from-tools)] 1876 | 1877 | # Contribuindo 1878 | 1879 | Nada de escrito neste guia é definitivo. É meu desejo trabalhar em conjunto com 1880 | todos os interessados no estilo de codificação em Clojure, para que possamos 1881 | criar um recurso que seja benéfico para toda a comunidade Clojure. 1882 | 1883 | Sinta-se à vontade para abrir tickets ou enviar pull requests com melhorias. 1884 | Agradeço antecipadamente por sua ajuda! 1885 | 1886 | 1887 | Você também pode apoiar o guia de estilo com contribuições financeiras via [gittip](https://www.gittip.com/bbatsov). 1888 | 1889 | [![Apoie via Gittip](https://rawgithub.com/twolfson/gittip-badge/0.2.0/dist/gittip.png)](https://www.gittip.com/bbatsov) 1890 | 1891 | # Licença 1892 | 1893 | ![Creative Commons License](http://i.creativecommons.org/l/by/3.0/88x31.png) 1894 | Este trabalho é licenciado sob 1895 | [Creative Commons Attribution 3.0 Unported License](http://creativecommons.org/licenses/by/3.0/deed.en_US) 1896 | 1897 | # Espalhe a Palavra 1898 | 1899 | Um guia de estilo dirigido pela comunidade é de pouca utilidade para uma 1900 | comunidade que não sabe sobre sua existência. Tweet sobre o guia, compartilhe 1901 | com seus amigos e colegas. Todos os comentários, sugestões ou opiniões que nós 1902 | recebemos faz o guia um pouco melhor. E queremos ter o melhor guia possível, não é? 1903 | 1904 | Felicidades,
1905 | [Bozhidar](https://twitter.com/bbatsov) 1906 | --------------------------------------------------------------------------------