Reputation: 1331
I'm exploring macros with basic examples and I do not understand how it works.
This :
(defmacro evalf [f v]
(f v))
(evalf + 2)
does not work.
I tried :
(defmacro evalf [f v]
'(f v))
(evalf + 2)
no luck...
I do not understand other syntaxes : ~ ~@ and so on but they does not work either. I see that symbol f is not pointing on + but I do not know to say "take the value of f which is +".
Can you make it clearer ? Thanks in advance
Upvotes: 1
Views: 109
Reputation: 13473
Try
(defmacro evalf [f v]
(list f v))
(evalf (partial * 2) 66); 132
In the call of evalf
(partial * 2)
and 66
;(list '(partial * 2) '66)
;
((partial * 2) 66)
132
.An alternative, using syntax quoting, is
(defmacro evalf [f v]
`(~f ~v))
Upvotes: 4
Reputation: 17859
Depending on what do you want to do there are two variants:
First one (the one you probably want) is:
(defmacro evalf [f v] `(~f ~v))
or
(defmacro evalf [f v] (list f v))
Both of them do the same thing: generate the s-expression you need.
With this one (evalf + 10)
would be expanded to (+ 10)
in compile-time, and then successfully evaluated in runtime.
Second one is this:
(defmacro evalf [f v] ((resolve f) v))
Now the function f
would be called at compile-time, so macro would be expanded to the result: 10
Your variant with (f v)
failed silently, because when you call (evalf + 10)
,
the +
here is just a plain symbol, not a reference to the function from macro's point of view, so it tries to call ('+ 10)
, since the symbol in clojure has function's semantics, it is totally correct syntax, but this call produces nil
. (the example of symbol call: ('+ {'+ 10})
=> 10) So if you want to get the function, named as this symbol, you will have to resolve it, as in my second example.
And the variant with '(f v)
just expands to the list of two symbols : 'f
and 'v
, and then leads to the runtime call ('f 'v)
that also returns nil
, like the first variant.
Upvotes: 5