The following is from Learn clojure in Y minutes.
fn - used to create a new function
> (fn [] "Hello World")
#<core$eval1256$fn__1257 learn_clojure.core$eval1256$fn__1257@590a8143>
> ((fn [] "Hello World"))
"Hello World"
def - used to create a var
> (def x 1)
#'learn-clojure.core/x
> x
1
> (def hello-world (fn [] "Hello World"))
#'learn-clojure.core/hello-world
> hello-world
#<core$hello_world learn_clojure.core$hello_world@4511e86f>
> (hello-world)
"Hello World"
> (defn hello-world [] "Hello World")
#'learn-clojure.core/hello-world
[] - defines the list of arguments for the function
> (defn hello [name]
\t(str "Hello " name))
#'learn-clojure.core/hello
While tabs are not always necessary in Clojure, they aid readability.
> (hello)
ArityException Wrong number of args (0) passed to: core/hello clojure.lang.AFn.throwArity (AFn.java:429)
> (hello "Neil")
"Hello Neil"
This is another way of defining functions:
> (def hello-again #(str "Hello " %1))
#'learn-clojure.core/hello
> (hello-again "Neil")
"Hello Neil"
Clojure allows variadic functions.
> (def hello-someone
\t([] "Hello World")
\t([name] (str "Hello " name)))
#'learn-clojure.core/hello-someone
> (hello-someone)
"Hello World"
> (hello-someone "Neil")
"Hello Neil")
Another way of defining a variadic function is by using the & operator to define packed arguments:
> (defn count-args [& args]
\t(str "You passed " (count args) " args: " args))
#'learn-clojure.core/count-args
> (count-args 1 2 3)
You passed 3 args: (1 2 3)
You can mix regular arguments with packed arguments:
> (defn hello-count [name & args]
\t(str "Hello " name ", you passed " (count args) " args"))
#'learn-clojure.core/hello-count
> (hello-count "Neil" 1 2 3)
"Hello Neil, you passed 3 args"