(def global-value '(5 4 3 2 1)) (defn impure-increment-numbers [number-collection] (map inc global-value)) (impure-increment-numbers '(1 2 3 4 5))
Side Effect: Printing to the console log
Although the following example is probably quite harmless, it is a simple example of a function effecting the state of something outside. These side effects should be avoided where possible to keep your code simpler to reason about.
(defn print-to-console [value-to-print] (println "The value is:" value-to-print)) (print-to-console "a side effect")
Side Causes: Calling libraries
(defn task-complete [task-name] (str "Setting task " task-name " completed on " (js/Date))) (task-complete "hack clojure")
(:import java.util.Date) (defn task-complete [task-name] (str "Setting task " task-name " completed on " (java.util.Date.))) (task-complete "hack clojure")
The function (java.util.Date.) is actually a call to instantiate a java.util.Date object. The full-stop character at the end of the name makes it a function call and is the short form of (new java.util.Date)
In this example we have called to the outside world to generate a value for us. The above example is fairly simple, however by calling the outside world rather than passing in a date it makes the functions purpose far less clear.
Re-write as a pure function
(defn task-complete [task-name completed-date] (str "Setting task " task-name " completed on " completed-date)) (task-complete "hack clojure" (js/Date))
Required values should be generated outside a function where possible. In this case in the
(js/Date) function is first evaluated and replaced by its value, then that date value is passed to the function as an argument, keeping the function pure.