It *is* possible, and not just if the private helper function is run
at macroexpansion time to massage forms for the macro. The macro *can*
output code that invokes the helper at runtime, but it's awkward:

user=> (ns foo)
nil
foo=> (defn- priv [x] (+ 2 x))
#'foo/priv
foo=> (defmacro call-priv-1 [x] `(priv ~x))
#'foo/call-priv-1
foo=> (defmacro call-priv-2 [x] `((deref (var priv)) ~x))
#'foo/call-priv-2
foo=> (macroexpand-1 '(call-priv-1 3))
(foo/priv 3)
foo=> (call-priv-1 3)
5
foo=> (macroexpand-1 '(call-priv-2 3))
(@#'foo/priv 3)
foo=> (call-priv-2 3)
5
foo=> (in-ns 'user)
#<Namespace user>
user=> (foo/call-priv-1 3)
#<CompilerException java.lang.IllegalStateException: var: #'foo/priv
is not public (NO_SOURCE_FILE:24)>
user=> (foo/call-priv-2 3)
5
user=>

As expected, foo/call-priv-1 doesn't work from outside foo. But
foo/call-priv-2 does.

Obviously this can be made a bit nicer with another couple of macros:

(defmacro pvar [sym]
  `(deref (var ~sym)))

(defmacro pfn [sym & args]
  `((pvar ~sym) ~@args))

Then call-priv-2 becomes

(defmacro call-priv-2 [x]
  `(pfn priv ~x))

which is *almost* as nice as a plain old

`(priv ~x)

like in call-priv-1.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to