Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is wrong with that form constructing?

Tags:

clojure

Considering that valid clojure form:

    > (let [a 16 b 8] (/ a b))
2

I am trying to construct it by hand in order to feed it into an eval call. I am rejected by the repl well before:

> (list 'let '[ 'a '16 'b '8 '] '(/ a b) )
RuntimeException Unmatched delimiter: ]  clojure.lang.Util.runtimeException (Util.java:156)
(/ a b)
RuntimeException Unmatched delimiter: )  clojure.lang.Util.runtimeException (Util.java:156)

Quoting the array characters [] is not enough. Indeed, the following expression (removing [ and ]) is ok:

> (list 'let  'a '16 'b '8  '(/ a b) )
(let a 16 b 8 (/ a b))

What is wrong with that construction? And how can I workaround that please? Is there any special form to quote [ and ] characters?

like image 779
yves Baumes Avatar asked May 18 '26 20:05

yves Baumes


2 Answers

If you are trying to generate code then I would recommend constructing this expression using auto-gensyms as below:

`(let [a# 16 b# 8] (/ a# b#))

The auto-gensyms (a# and b#) create symbol names that are guaranteed to be unique. This isn't strictly necessary, but in more complex cases it can help to avoid variable names getting accidentally captured (e.g. by different levels of macro expansion).

Note the use of the syntax-quote (`) rather than the regular quote (') at the beginning of the expression. This is usually better than a regular quote when you are generating code because it handles namespaces automatically.

like image 77
mikera Avatar answered May 21 '26 20:05

mikera


You can quote the entire vector:

(list 'let '[a 16 b 8] '(/ a b))
like image 36
mtyaka Avatar answered May 21 '26 19:05

mtyaka



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!