Hi! I'm understand macros from other Lisp, and I implemented some simple Lisp interpreters (not compilers) in Java and C#.
But I still don't understand some Clojure decisions, like indicating something is a macro in the metadata of a var. I guess those decisions are related to COMPILING phase. Today, I found an unexpected error. In a clear REPL: user=> (declare myfn2) #'user/myfn2 user=> (defn myfn1 [x y] (myfn2 x y)) #'user/myfn1 user=> (defn myfn2 [x y] (+ x y)) #'user/myfn2 user=> (myfn1 1 2) 3 This is OK. But again, in a new/clear REPL: user=> (declare myfn2) #'user/myfn2 user=> (defn myfn1 [x y] (myfn2 x y)) #'user/myfn1 user=> (defmacro myfn2 [x y] (cons 'list (cons x (cons y nil)))) #'user/myfn2 user=> (myfn1 1 2) ArityException Wrong number of args (2) passed to: user/myfn2 clojure.lang.AFn. throwArity (AFn.java:429) Why? I expected something like: - Invoke the macro - Or invalid call to macro but why "wrong number of args"? In the same REPL, I continue with: user=> (defn myfn1 [x y] (myfn2 x y)) #'user/myfn1 user=> (myfn1 1 2) (1 2) So, I redeclare myfn1, using myfn2 that now it is known as a macro, I invoked myfn1 and myfn2 was invoked. OK. But now, if I redeclare myfn2 to a normal function: user=> (defn myfn2 [x y] (+ 1 2)) #'user/myfn2 user=> (myfn1 1 2) (1 2) user=> (myfn2 1 2) 3 THE invocation to myfn1 is using the OLD myfn2 definition. My guess: - myfn1 was compiled, and at the time of compilation, myfn2 was a macro, with some implementation The questions are: Am I right? It is a compiler related issue when using macros? How myfn1 knows the PAST implementation of myfn2? It is the myfn2 initial implementation EXPANDED at myfn1 compile time? What happens if myfn2 has other macros inside? In other implementations, I expected myfn1 lookup for myfn2 value EACH TIME myfn2 is used at head of list, independently of being myfn2 a macro or not. For example, in a clear REPL user=> (defn myfn2 [x y] (+ x y)) #'user/myfn2 user=> (defn myfn1 [x y] (myfn2 x y)) #'user/myfn1 user=> (myfn1 1 2) 3 It's OK. Then, I redefined myfn2: user=> (defn myfn2 [x y] (+ x y 1)) #'user/myfn2 user=> (myfn1 1 2) 4 and THE NEW myfn2 is indirectly invoked. TIA Angel "Java" Lopez @ajlopez -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to [email protected] Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
