Hi Paul,

Pure functions have two properties: they cannot produce side effects
and the return value is a function (in the mathematical sense) of its
arguments and nothing else. There are two corresponding questions that
you can ask when looking at a function to determine if it is pure.

1) When I call this function with the same arguments, do I always get
the same result?
2) Is it true that the only reason you would ever call this function
is to obtain the value that is returned from it?

If the answer to both of these questions is Yes, then you are looking
at a pure function.

Consider the following code:

(defn calc [x y] (+ x y))
(defn foo [x y] (calc x y))

Both are pure. If I call (foo 1 1) I will always get 2. There are no
side effects. Same for calc.

However, any caller can do this:

(binding [calc #(* 10 %1 %2)] (foo 1 1))

Does this mean that the function foo in now impure? No. It just means
that someone is abusing Clojure and looking for trouble.

An impure version of our code would look like this:

(declare *something*)
(defn calc [x y] (+ x y))
(defn foo [x y] (calc (/ x *something*) y))

The earmuffs are the idiomatic Clojure way of indicating that
something is intended to be dynamically bound. The caller must bind
*something* to a value or this code will not work. This is what
"Programming Clojure" means when it states: "Functions that use
dynamic bindings are not pure functions..", it is not referring to
functions which use binding internally (as in your example) but to
functions which depend on values that are dynamically bound outside of
said function.

If we wanted to have a default value for something, we could write:

(def *something* 42)
(defn calc [x y] (+ x y))
(defn foo [x y] (calc (/ x *something*) y))

In this case, there is nothing objective about foo that makes it pure
or impure. If *something* where a constant then it would be a pure
function, but if it is intended to be rebound, it is not. You only
know that is it impure based on the intention that is communicated by
the developer and the idiomatic use of earmuffs.

In summary: In some cases it is obvious, in others we only know by
intention and in call cases we can abuse Clojure and make every
function impure.

Brenton

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to