Arc Forumnew | comments | leaders | submitlogin
2 points by zck 2992 days ago | link | parent

Clojure also has a pretty cool way to not have to call (uniq) by hand. If, inside a backquote, you append a # to a symbol, clojure will replace that variable with a gensym. And it'll use the same gensym every time you use that variable in the backquoted form.

Here's the source for `and` (https://github.com/clojure/clojure/blob/clojure-1.7.0/src/cl...):

    (defmacro and
      "Evaluates exprs one at a time, from left to right. If a form
      returns logical false (nil or false), and returns that value and
      doesn't evaluate any of the other expressions, otherwise it returns
      the value of the last expr. (and) returns true."
      {:added "1.0"}
      ([] true)
      ([x] x)
      ([x & next]
       `(let [and# ~x]
          (if and# (and ~@next) and#))))
See how it uses and#, but it doesn't capture the variable and?

I'm not entirely sure how you would capture a variable (e.g., Arc's "aand"); if you try to, clojure errors by default. There's probably some way, but I don't know offhand.



3 points by rocketnia 2990 days ago | link

This StackOverflow answer ends with "I'd recommend a real anaphoric macro" and gives an example: http://stackoverflow.com/questions/9764377/how-to-avoid-anap...

Based on that, I found this way to write aand, which seems to work at http://www.tutorialspoint.com/execute_clojure_online.php:

  (defmacro aand
    ([] true)
    ([x] x)
    ([x & next]
     `(let [~'it ~x]
        (if ~'it (aand ~@next) ~'it))))
  
  (prn (aand "woo" (list it it) (list it it it)))
It looks like Clojure macros can capture variables in the other direction too, like Arc:

  (defmacro capture-it
    ([] 'it))
  
  (prn (let [it "woo"] (capture-it)))

-----