clojureFunctions

Defining Functions

Functions are defined with five components:

The header, which includes the defn keyword, the name of the function.

(defn welcome ....)

An optional Docstring that explains and document what the function does.

(defn welcome 
    "Return a welcome message to the world"
     ...)

Parameters listed in brackets.

(defn welcome 
    "Return a welcome message"
    [name]
    ...)

The body, which describes the procedures the function carries out.

(defn welcome 
    "Return a welcome message"
    [name]
    (str "Hello, " name "!"))

Calling it:

=> (welcome "World")

"Hello, World!"

Parameters and Arity

Clojure functions can be defined with zero or more parameters.

(defn welcome
    "Without parameters"
    []
    "Hello!")

(defn square
    "Take one parameter"
    [x]
    (* x x))

(defn multiplier
    "Two parameters"
    [x y]
    (* x y))

Arity

The number of arguments a function takes. Functions support arity overloading, which means that functions in Clojure allow for more than one "set" of arguments.

(defn sum-args
  ;; 3 arguments
  ([x y z]
     (+ x y z))
  ;; 2 arguments
  ([x y]
     (+ x y))
  ;; 1 argument 
  ([x]
     (+ x 1)))

The arities don't have to do the same job, each arity can do something unrelated:

(defn do-something
  ;; 2 arguments
  ([first second]
     (str first " " second))
  ;; 1 argument 
  ([x]
     (* x x x)))

Defining Variadic Functions

A Clojure function can be defined to take an arbitrary number of arguments, using the symbol & in its argument list. All remaining arguments are collected as a sequence.

(defn sum [& args]
  (apply + args))

(defn sum-and-multiply [x & args]
  (* x (apply + args)))

Calling:

=> (sum 1 11 23 42)
77

=> (sum-and-multiply 2 1 2 3)  ;; 2*(1+2+3)
12

Defining anonymous functions

There are two ways to define an anonymous function: the full syntax and a shorthand.

Full Anonymous Function Syntax

(fn [x y] (+ x y))

This expression evaluates to a function. Any syntax you can use with a function defined with defn (&, argument destructuring, etc.), you can also do with with the fn form. defn is actually a macro that just does (def (fn ...)).

Shorthand Anonymous Function Syntax

#(+ %1 %2)

This is the shorthand notation. Using the shorthand notation, you don't have to name arguments explicitly; they'll be assigned the names %1, %2, %3 and so on according to the order they're passed in. If the function only has one argument, its argument is called just %.

When To Use Each

The shorthand notation has some limitations. You can't destructure an argument, and you can't nest shorthand anonymous functions. The following code throws an error:

(def f #(map #(+ %1 2) %1))

Supported Syntax

You can use varargs with shorthand anonymous functions. This is completely legal:

#(every? even? %&)

It takes a variable number of arguments and returns true if every one of them is even:

(#(every? even? %&) 2 4 6 8)
;; true
(#(every? even? %&) 1 2 4 6)
;; false

Despite the apparent contradiction, it is possible to write a named anonymous function by including a name, as in the following example. This is especially useful if the function needs to call itself but also in stack traces.

(fn addition [& addends] (apply + addends))