Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

trying to understand a clojure "let" example

Tags:

clojure

(defn make-adder [x]
  (let [y x]
    (fn [z] (+ y z))))
(def add2 (make-adder 2))
(add2 4)
-> 6

I am trying to figure out this let example in clojure. What is the y variable it never seems to be set to anything. I do not understand the let syntax.

like image 877
eat_a_lemon Avatar asked Mar 05 '14 17:03

eat_a_lemon


People also ask

What does let mean in Clojure?

Sign up. Clojure let is used to define new variables in a local scope. These local variables give names to values. In Clojure, they cannot be re-assigned, so we call them immutable.

What is def in Clojure?

def is a special form that associates a symbol (x) in the current namespace with a value (7). This linkage is called a var . In most actual Clojure code, vars should refer to either a constant value or a function, but it's common to define and re-define them for convenience when working at the REPL.

Does Clojure have closures?

This is a perfect opportunity to enforce encapsulation to avoid drowning the client in board-implementation details. Clojure has closures, and closures are an excellent way to group functions (Crockford 2008) with their supporting data.


3 Answers

(let [y x]
    <body>)

evaluates <body> in a lexical context where y is bound to the value of x.

See the Clojure documentation for the description of let syntax. The general form is:

(let [sym1 val1
      sym2 val2
      sym3 val3
      ... ]
    <body>)

Each symN is bound to the corresponding valN.

like image 143
Barmar Avatar answered Oct 27 '22 14:10

Barmar


This function:

(defn make-adder [x]
  (let [y x]
    (fn [z] (+ y z))))

Itself returns a first-class function (a function that can be returned, passed around and assigned to a name just like any other value). Inside the let, x is bound to y, and so the function above is equivalent to this function below:

(defn make-adder [x]
  (fn [z] (+ x z)))

So that when make-adder is called with the value 2, it returns this first-class function:

(fn [z] (+ 2 z))

Remember, a first-class function can be assigned to a name, as in this line:

(def add2 (made-adder 2))

The line above is therefore equivalent to this code:

(def add2 (fn [z] (+ 2 z)))

And so is equivalent to this code also:

(defn add2 [z] (+ 2 z))

Which means that when add2 is called:

(add2 4)

The expression above evaluates to this:

(+ 2 4)

Which evaluates to 6.

like image 11
djhaskin987 Avatar answered Oct 27 '22 16:10

djhaskin987


Let expression is standard in many functional programming languages. What is the "let" keyword in functional languages like F# and OCaml for?

like image 1
aarti Avatar answered Oct 27 '22 15:10

aarti