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

Popular posts from this blog

java - SSE Emitter : Manage timeouts and complete() -

jquery - uncaught exception: DataTables Editor - remote hosting of code not allowed -

java - How to resolve error - package com.squareup.okhttp3 doesn't exist? -