0

I am trying co join two list using map and logical function "and"

(map and '(true false true) '(0 1 2))

I expect to see

(0 false 2)

Instead of that

CompilerException java.lang.RuntimeException: Can't take value of a macro:
#'clojure.core/and, compiling:(NO_SOURCE_PATH:274:1)

occures.

How can I fix it?

boucekv
  • 1,220
  • 2
  • 20
  • 47
  • user=> (apply and [true false]) CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/and, compiling:(NO_SOURCE_PATH:280:1) user=> (apply + [1 2]) 3 – boucekv Nov 14 '13 at 12:04
  • [Use vectors instead of quoted lists](http://stackoverflow.com/questions/3896542/in-lisp-clojure-emacs-lisp-what-is-the-difference-between-list-and-quote/3897581#3897581) – Alex Taggart Nov 14 '13 at 14:04

2 Answers2

4

You can wrap the "and" macro into a function

(map #(and % %2) '(true false true) '(0 1 2))

Result:(0 false 2)

The map function don't let you to use macros as first argument, so this is an easy trick to solve the problem

tangrammer
  • 3,041
  • 17
  • 24
2

accepted answer is definitely solid, I just wanted to give you an example of converting a macro to a function (mostly for entertaining/learning purposes):

(defmacro to-fun [macro]       ;; converting a macro to a function 
  `#(eval (cons '~macro %&)))  ;; e.g. "eval"uated at run time vs. compile time, 
                               ;; and hence can be composed

now we can just wrap a(ny) macro with it:

(map (to-fun and) [true false true] [0 1 2])
(0 false 2) 

or:

(map (to-fun or) [true false true] [0 1 2])
(true 1 true)
tolitius
  • 22,149
  • 6
  • 70
  • 81
  • Thank you very much. So the problem is the map must get a function and can not work with macro? – boucekv Nov 15 '13 at 07:14
  • yes. the first argument to a map is a function. what map does, it _[applies](https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L2516)_ this function to elements in these collections. In order for any function to be _applied_ (read "called"), it needs to have an apply "method" (in Clojure source it is called [applyTo](https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/AFn.java#L150)). macro is evaluated at compile time, to usually something other than a "function", and that "somethin other" does not have such a "method" (e.g. can't be _applied_). – tolitius Nov 15 '13 at 15:26