I'm trying to read up a bit on Clojure, but I hit a brick wall with the following basic example:
(defn make-adder [x]
(let [y x]
(fn [z] (+ y z))))
(def add2 (make-adder 2))
(add2 4)
-> 6
What I don't understand is how is add2
passing the number 4 to the make-adder function, and how does that function turn assigns that number to z.
Thanks in advance!
It provides the tools to avoid mutable state, provides functions as first-class objects, and emphasizes recursive iteration instead of side-effect based looping. Clojure is impure, in that it doesn’t force your program to be referentially transparent, and doesn’t strive for 'provable' programs.
Clojure supports arity overloading in a single function object, self-reference, and variable-arity functions using &: You can create local names for values inside a function using let. The scope of any local names is lexical, so a function created in the scope of local names will close over their values:
They can be assigned as values, passed into functions, and returned from functions. It’s common to see function definitions in Clojure using defn like (defn foo …
An anonymous function is a function without a name. In Clojure these can be defined in two ways, fn and the literal # (… ) . Creating a function with defn immediately binds it to a name, fn just creates a function. Let’s have an example with a few music bands:
make-adder
returns a function that takes one parameter (z), the parameter passed in to make-adder
is used to assign a value to y. add2
is set equal to the result of evaluating make-adder
with a parameter of 2. So add2
is set equal to the function returned from make-adder
, which (since y has been assigned to the parameter from make-adder
) looks like
(fn [z] (+ 2 z))
So (add2 4)
calls this function which evaluates to 6. Does that help?
To me, it seems you are working on an interesting problem.
Your example make-adder function (rewritten without let bindings)
(defn make-adder [x]
"Returns a function that returns the sum of x and yet to be supplied z."
(fn [z] (+ z x))))
returns a function that sums x and z, where make-adder has to have already been called with a value. I believe your example is implementing the Clojure partial function, which is pretty cool.
Here is your make-adder function rewritten to sum its two parameters, and not return a function (so we can use partial in add2),
(defn make-adder
"Returns sum of x and y."
[x y]
(+ x y))
and here is add2 rewritten using partial with 2 as the x parameter:
(def add2 (partial make-adder 2))
If I call (add2 2)
the answer is 4, (add2 3)
, the answer is 5 and so on.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With