Functions in Clojure (11/07/2020)

Languages > Clojure

Using functions

('functionname' 'parameters' 'if' 'any')

Creating functions

Generic syntax

(defn 'functionanme' ['parameters' 'if' 'any'] ('body'))

Multi-arity functions

(defn hello
   ([] (hello "world"))   ;An arity can use another.
   ([who] (println "Hello " who)))

Variadic functions

(defn hello [& who] (println "Hello " who)  ;'who' can contain any number of parameters.

Anonymous functions

Classic syntax

(fn ['parameters' 'if' 'any'] ('body'))

Alternative syntax

#(println "Hello " %) ;Equivalent to (fn [who] (println "Hello " who)
#(println "Hello " %1 %2)  ;Equivalent to (fn [who1 who2] (println "Hello " who1 Who2))
#(println "Hello " %&)  ;Equivalent to (fn [& who] (println "Hello " who)

Note about defn

‘defn’ is a contraction of ‘def’ and ‘fn’, it creates an anonymous function and associates it with a symbol. The following expressions are equivalents:

(defn hello [who] (println "Hello " who))
(def hello (fn [who] (println "Hello " who)))

Applying functions

The ‘apply’ function call the given function with the given parameters, drawing the last needed ones from the list given as last parameter:

(apply 'functionname' 'param1' 'param2' ('param3' 'param4'))

Lexical scopes and closures

Let

‘let’ binds symbols to values in a “lexical scope”. This associations exist only in the let context, and take precedence on the ones external to this context.

(let [x 1 y 2] (+ x y))  ;x and y only exist in the let.

Closure

(defn say [what] (fn [who] (println what who)))  ;Closes over 'what'.
(def sayHello (say "Hello"))  ;'sayHello' is a closure.
(sayHello "Blaise")  ;Will print "Hello Blaise".

Interoperability with Java

Java can be called from Clojure:

(Widget. "foo")  ;Instantiation. Equivalent to 'new Widget("foo") in Java.
(.nextInt rnd)  ;Calling an instance method. Equivalent to 'rnd.nextInt()' in Java.
(.-field object)  ;Accessing an instance field. Equivalent to 'object.field' in Java.
(Math/sqrt 124)  ;Calling a static method. Equivalent to 'Math.sqrt(124)' in Java.
(Math/PI)  ;Accessing a static field. Equivalent to 'Math.PI' in Java.

Java methods are not Clojure functions. They can’t be stored or passed as arguments. But they can be wrapped in functions if necessary:

(defn length [obj] (.length obj))

Clojure REPL (Previous chapter) < Functions in Clojure > (Next chapter) Clojure’s collections

Something to say?

Leave a Reply

Your email address will not be published.