Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Clojure, how to define a variable named by a string?

Given a list of names for variables, I want to set those variables to an expression.

I tried this:

(doall (for [x ["a" "b" "c"]] (def (symbol x) 666)))

...but this yields the error

java.lang.Exception: First argument to def must be a Symbol

Can anyone show me the right way to accomplish this, please?

like image 584
Carl Smotricz Avatar asked Mar 21 '10 10:03

Carl Smotricz


People also ask

How to define variables in Clojure?

In Clojure, variables are defined by the 'def' keyword. It's a bit different wherein the concept of variables has more to do with binding. In Clojure, a value is bound to a variable.

What is def 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.

What is let in Clojure?

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.


2 Answers

Clojure's "intern" function is for this purpose:

(doseq [x ["a" "b" "c"]]
  (intern *ns* (symbol x) 666))
like image 97
Stuart Sierra Avatar answered Oct 20 '22 04:10

Stuart Sierra


(doall (for [x ["a" "b" "c"]] (eval `(def ~(symbol x) 666))))

In response to your comment:

There are no macros involved here. eval is a function that takes a list and returns the result of executing that list as code. ` and ~ are shortcuts to create a partially-quoted list.

` means the contents of the following lists shall be quoted unless preceded by a ~

~ the following list is a function call that shall be executed, not quoted.

So ``(def ~(symbol x) 666)is the list containing the symboldef, followed by the result of executingsymbol xfollowed by the number of the beast. I could as well have written(eval (list 'def (symbol x) 666))` to achieve the same effect.

like image 21
sepp2k Avatar answered Oct 20 '22 03:10

sepp2k