Head into Clojure – Part 3: Functions

Creating Functions

We have to use functions at some point, Clojure is after all a Functional programming language.


(def hello (fn [] "Hello World"))                    ;; Defines a function, no parameters
(hello)                                              ;; call a function

(defn hello2 [] "hello world")                       ;; Use a macro to define a function
(hello2)                                             ;; No difference in way to call the function

(defn hello-to [name] (println "Hello" name))        ;; Define a function with a parameter
(hello-to "Keith")                                   ;; Call a function

(defn hello3-to [name, age]                          ;; Define a function with multiple parameters
    (println "Hello" name "you are " age))
(hello2-to "keith" 21)                               ;; Call a function with multiple parameters

 (defn hello-to-some                                 ;; Define a function which has 3 polymorphic methods
    ([] (println "Hello to no one"))                 ;; No parameters
    ([x] (println "Hello to " x))                    ;; One parameter
    ([x y] (println "Hello to " x " and " y)))       ;; Two parameters
(hello-to-some)
(hello-to-some "keith")
(hello-to-some "keith" "cat")

Functions on Collections

Now we know how to creation functions, we can use this new knowledge to do some basic manipulation of collections


(defn squareit [x] (* x x))                          ;; Define a method to square a number
(squareit 3)                                         ;; Test it, should return 9
(map squareit [1 2 3 4 5])                           ;; Applies squareit to every item of the collection
                                                     ;; returning a new collection with new values
                                                     ;; Should return (1 4 9 16 25)
(map squareit '(1 2 3 4 5))                          ;; Same as above, this time against a list


(defn more-than-one-char [x] (> (count x) 1))        ;; Filter takes a function that returns a boolean result
                                                     ;; Called a predicate in Clojure land
                                                     ;; This filter returns true if the string is > 1 character
(filter more-than-one-char ["a" "ab" "abc"])         ;; Applies the filter to a string, should return ("ab" "abc")

;; More often than not, there is already a function that can be used. In fact in <a href="http://www.keithsterling.com/?p=518" title="Head into Clojure – Part 1: The Basics">Part 1</a> we saw lots of mathematical and
;; boolean functions +, -, *, /, mod, inc dec etc
 
(map inc [1 2 3])                                    ;; Increments each element of the collection by 1
(map dec [1 2 3])                                    ;; Decreases each element by 1  

(filter even? [1 2 3 4 5 6 7 8 9 10])                ;; Filters out all odd numbers, returning a collection of evens
(filter float? [1 2.0 3 4 5.0])                      ;; Creates a collection of only floats

;; A slightly more advance, but equally important function is reduce. This takes the first item in the list, and applies
;; the define function to it and the next item. The result is them applied to the 3rd item and on and on through to the end 
;; of the list. This is best explained with a basic example using the + function

(reduce + [5 8 14 21])                               ;; Here reduce takes 5 and applies + to it and 8, result 13
                                                     ;; 13 then forms the left hand side of the method call, 
                                                     ;; 14 on the right hand side, the result being 27
                                                     ;; 27 is then the left and 21 the right, result 48
(+ (+ (+ 5 8) 14) 21)                                ;; The equivalent if you wrote it out long hand
                                                     ;; but this would be impossible if you didn't know the length
                                                     ;; of the collection in the first place
  
Be Sociable, Share!