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.

Reply via email to