On Nov 7, 5:41 pm, Stuart Halloway <[EMAIL PROTECTED]> wrote:
> Hi Rich,
>
> Sorry for being unclear. define-ant-task will be called as I
> reflectively walk Ant's object model. A more complete listing follows.
> The problem is that I am passing (.getKey td) to the macro, where
> (.getKey td) returns a string--or would if I evaled it :-)
>

No problem. I phrased things the way I did because the answer to all
macro problems usually lies in answering those 2 questions.

So I'll ask again:

What do you want to write?

What do you want it to expand into?

For instance, where does ant-project come from?

I could imagine an answer like this -

I want to write:

(generate-ant-tasks "my-ant-project-name")

And I want it to expand into:

(def task-name1 (create-ant-task "task-name1"))
(def task-name2 (create-ant-task "task-name2"))
(def task-name3 (create-ant-task "task-name3"))
...

for every task in the project.

But again. I don't know the ant model or pattern of use you want.

Generally speaking, because defs have special evaluation rules, to
generate defs your top-level call should be a macro, i.e. def is not
something you call, it is something you emit, which in turn gets
compiled. Internally your macro can use functions and even do the walk
of the ant model. Because it can only yield one expansion form, what
it will actually emit will be:

(do
  (def ...)
  (def ...))

Rich


>
> P.S. The whole thing is athttp://github.com/stuarthalloway/lancet/tree/master
> .
>
> (defn instantiate-task [project name props]
>    (let [task (.createTask project name)]
>      (throw-if (nil? task) (str "No task named " name))
>      (doto task
>        (init)
>        (setProject project))
>      (set-properties! task props)
>      task))
>
> (defn create-ant-task [task-name]
>    (fn f
>      ([]
>         (f {}))
>      ([props]
>         (let [task (instantiate-task ant-project task-name props)]
>          (.execute task)))))
>
> (defmacro define-ant-task [task-name]
>    `(def ~(symbol task-name) (create-ant-task ~task-name)))
>
> (doseq td (.getTaskDefinitions ant-project)
>   (do
>     (println (.getKey td))
>     (define-ant-task (.getKey td))))
>
>
>
> > On Nov 7, 3:48 pm, Stuart Halloway <[EMAIL PROTECTED]> wrote:
> >> The following macro in lancet defines an ant task.
>
> >>   (defmacro define-ant-task [task-name]
> >>     `(def ~(symbol task-name) (create-ant-task ~task-name)))
>
> >> (At least) one of the following assumptions is wrong:
>
> >> (1) define-ant-task needs to be a macro so it can drop args into def.
>
> >> (2) define-ant-task needs to be a function because task-name needs to
> >> be evaled on the way in.
>
> >> (3) using eval (which would solve the contradiction in 1 & 2) is evil
> >> and should be avoided.
>
> >> On a quick look through boot.clj and other places I don't see any
> >> other macros that deal with this issue, which makes me think there is
> >> some totally different way to approach the problem.
>
> >> Suggestions?
>
> > It's common for people to post only their macros, but actually more
> > useful to (additionally) post:
>
> > What I'd like to say (what a usage would look like)
>
> > What I'd like that to expand into
>
> > Doing so can greatly clarify things. For instance it's not clear to me
> > what you will be passing to define-ant-task if not a symbol, so I
> > don't understand the call to symbol inside.
>
> > Rich
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to [email protected]
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to