qed
qed

Reputation: 23134

make sure that a macro inside a let form has access to local vars

Here is an example:

(defmacro aupdate-in [a i f & args]
  `(do
     (aset ~a ~i (~f (aget ~a ~i) ~@args))
     a))
(let [a (long-array [1 2 3 4])]
  (do
    (aupdate-in a 2 * 5)
    (pprint (vec a))))

This gives an error:

CompilerException java.lang.RuntimeException: No such var: cina.fn-browser/a, compiling:(/Users/kaiyin/personal_config_bin_files/workspace/cina/src/cina/fn_browser.clj:20:16)

I can modify a bit and make it work:

(defmacro aupdate-in [a i f & args]
  (list 'do
        (list 'aset a i
              (list* f
                     (list 'aget a i) args))))
(let [a (long-array [1 2 3 4])]
  (do 
    (aupdate-in a 2 * 5)
    (pprint (vec a))))

But all the list list* stuff looks really ugly. Is there a better solution?

Upvotes: 0

Views: 57

Answers (1)

sw1nn
sw1nn

Reputation: 7328

You need to unquote a so that it refers to the symbol passed in:

(defmacro aupdate-in [a i f & args]
  `(do
     (aset ~a ~i (~f (aget ~a ~i) ~@args))
     ~a))

Upvotes: 1

Related Questions