Skip to content

Examples Guidelines Draft

zkim edited this page Sep 14, 2010 · 11 revisions

ClojureDocs examples guidelines (draft)

Purpose

The example sections on each var page are there to provide simple, isolated examples of var usage.

Examples should be easy to grok. This is a highly subjective criterion, which is why we've outlined some easy to follow guidelines below.

General

Examples should be short, unique, self-contained snippets of code that illustrate var usage in the simplest possible way. Short, sweet, and complete is the name of the game.

Examples should be as stand-alone as possible, try to imagine clear conceptual boundries of your example before submitting it. You should assume the reader is coming from a programming background, with little (but some) Clojure experience.

If the target var is not part of the core ns (or otherwise not 'use'd by the repl by default) please include the use / require statement. (Should we nix this as well, the ns is at the top of the page anyway? pros: make examples more readable / shorter, cons: lots of questions about not found errors)

Each example should be either broad, or deep, not both. For example, the following example for not= shows the broad range of inputs allowed. (need to find a var that has both broad and deep examples)

user=> (not= 1 1)
false

user=> (not= 1 2)
true

user=> (not= true true)
false

user=> (not= true false)
true

user=> (not= true true true true)
false

user=> (not= true true false true)
true

Whereas this example for future has depth. ;; A future is calculated in another thread user=> (def f (future (Thread/sleep 10000) 100)) #'user/f

;; When you dereference it you will block until the result is available.
user=> @f
100

;; Dereferencing again will return the already calculated value immediately.
user=> @f
100

Gotchas??

Comments

Short, specific comments should directly precede the code block which they describe, don't put a line break before the block.

Longer / complex comments, or overarching comments may have a line break after the comment

Bad: user=> (with-precision 10 (/ 1M 3)) 0.3333333333M

;; The "M" suffix denotes a BigDecimal instance
;; http://download.oracle.com/javase/6/docs/api/java/math/BigDecimal.html
user=> (.floatValue 0.3333333333M)
0.33333334

Good: ;; The "M" suffix denotes a BigDecimal instance ;; http://download.oracle.com/javase/6/docs/api/java/math/BigDecimal.html

user=> (with-precision 10 (/ 1M 3))
0.3333333333M

user=> (.floatValue 0.3333333333M)
0.33333334

General commentary about the following example should be first, and separated from the rest of the example by two (?) blank lines.

;; should be used before a block of text for a general comment about that block, ; should be used if the example is complex enough to warrant a call-out on a specific line within a block.

Lines to be executed should start with user=>, not user>, >. This will help with automatic verification. Hinders copy/paste (all those user=>'s show up on paste)

definitions (def, defn, defmacro, etc) can leave out the user=>

Good: ;; You can use destructuring to have keyword arguments. This would be a pretty ;; verbose version of map (in an example a bit more verbose than the first above): (defn keyworded-map [& {function :function sequence :sequence}] (map function seq))

;; You can call it like this:
user=> (keyworded-map :sequence [1 2 3] :function #(+ % 2))
(3 4 5)


;; The declaration can be shortened with ":keys" if your local variables should be
;; named in the same way as your keys in the map:
(defn keyworded-map [& {:keys [function sequence]}]
  (map function sequence))

Comments are not required for very simple examples.

Formatting / Indentation

Line width should follow the standard convention of a maximum of ?? characters.

Leave one line of whitespace after output from the repl.

Good: user=> (println "foo") foo nil

user=> (println "bar")
bar
nil

user=> (println "baz")
baz
nil

Bad: user=> (println "foo") foo nil user=> (println "bar") bar nil user=> (println "baz") baz nil

Use proper Clojure indenting guidelines (which are??)

for binding (??) lists, use proper line breaks at the key-val border

Bad: user=> (def digits (seq [1 2 3])) #'user/digits

user=> (for [x1 digits x2 digits] (* x1 x2))
(1 2 3 2 4 6 3 6 9)

Good: user=> (def digits (seq [1 2 3])) #'user/digits

user=> (for [x1 digits 
             x2 digits] 
         (* x1 x2))
(1 2 3 2 4 6 3 6 9)

Linking

Clone this wiki locally