Clojure - Using a variable as a function call -
i trying make simple clojure macro applies inputted function twice: (f (f args))
, (e.g (inc (inc 4)) => 6
)
the problem is, when run below code using (reapply-function '(inc 4))
, nil
. doesn't make sense me since can print out both value of f
, result inc
, 5
. there must simple thing i'm missing. can see issue?
(defmacro reapply-function [args] (list 'let ['f (list 'first (list 'quote args)) 'result args] (list 'f 'result)))
initial note
this answer provided assuming you're trying learn use macros own sake. agree @thumbnail's answer: don't use macros except when absolutely, positively cannot avoid -- , not 1 of times.
shorter implementation
consider:
(defmacro reapply-function [[func & rest]] `(~func (~func ~@rest)))
macroexpand
demonstrates how works:
user=> (macroexpand '(reapply-function (inc 4))) (inc (inc 4))
...and functions in repl:
user=> (reapply-function (inc 4)) 6
...but why didn't original work?
with original implementation, macroexpand-1
gives this:
(let [f (first (quote (inc 4))) result (inc 4)] (f result))
...which indeed evaluate nil
.
but why? in short: f
is, in code, symbol, not function symbol points to.
thus, make shortest possible change makes original code function:
(defmacro reapply-function [args] (list 'let ['f (list 'first (list 'quote args)) 'result args] (list '(resolve f) 'result)))
Comments
Post a Comment