I'm trying to build something using macros ... my long goal is a
simple embedded DSL.  Here's a simplified version:


(defmacro to-fn
  "Converts a collection of forms into an anonymous function of no arguments."
  [forms]
  `(fn [] ~...@forms))

(defn run-example
  [fn]
  (printf "BEFORE\n")
  (fn)
  (printf "AFTER\n"))

(defmacro example
  [& code]
  `(let [fn# (to-fn ~code)]
    (run-example fn#)))

(example (printf "EXAMPLE1\n") (printf "EXAMPLE2\n"))

This gives the expected output:

BEFORE
EXAMPLE1
EXAMPLE2
AFTER

Now, the problem is, I want to manipulate the list of forms passed to
the example macro before turning it into (to-fn) (the real DSL will
split the forms into groups and create multiple functions, and this is
all about the side-effects).

Changing the macro as so:

(defmacro example
  [& code]
  `(let [rcode# ~(reverse code)
        fn# (to-fn rcode#)]
    (run-example fn#)))

Give me an exception:

java.lang.RuntimeException: java.lang.RuntimeException:
java.lang.IllegalArgumentException: Don't know how to create ISeq
from: Symbol (p0-01.clj:42)
        at clojure.lang.Compiler.analyze(Compiler.java:4032)
        at clojure.lang.Compiler.analyzeSeq(Compiler.java:4176)
        at clojure.lang.Compiler.analyze(Compiler.java:4017)
        at clojure.lang.Compiler.access$100(Compiler.java:38)
        at clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:3790)
        at clojure.lang.Compiler.analyzeSeq(Compiler.java:4188)
        at clojure.lang.Compiler.analyze(Compiler.java:4017)
        at clojure.lang.Compiler.analyzeSeq(Compiler.java:4176)
        at clojure.lang.Compiler.analyze(Compiler.java:4017)
        at clojure.lang.Compiler.analyzeSeq(Compiler.java:4176)
        at clojure.lang.Compiler.analyze(Compiler.java:4017)
        at clojure.lang.Compiler.analyze(Compiler.java:3978)
        at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:3678)
        at clojure.lang.Compiler$FnMethod.parse(Compiler.java:3513)
        at clojure.lang.Compiler$FnMethod.access$1100(Compiler.java:3390)
        at clojure.lang.Compiler$FnExpr.parse(Compiler.java:2952)
        at clojure.lang.Compiler.analyzeSeq(Compiler.java:4186)
        at clojure.lang.Compiler.analyze(Compiler.java:4017)
        at clojure.lang.Compiler.eval(Compiler.java:4222)
        at clojure.lang.Compiler.load(Compiler.java:4548)
        at clojure.lang.Compiler.loadFile(Compiler.java:4515)
        at clojure.main$load_script__5665.invoke(main.clj:206)
        at clojure.main$script_opt__5696.invoke(main.clj:258)
        at clojure.main$main__5720$fn__5722.invoke(main.clj:333)
        at clojure.main$main__5720.doInvoke(main.clj:328)
        at clojure.lang.RestFn.invoke(RestFn.java:413)
        at clojure.lang.Var.invoke(Var.java:340)
        at clojure.lang.AFn.applyToHelper(AFn.java:173)
        at clojure.lang.Var.applyTo(Var.java:457)
        at clojure.main.main(main.java:39)
Caused by: java.lang.RuntimeException: java.lang.RuntimeException:
java.lang.IllegalArgumentException: Don't know how to create ISeq
from: Symbol
        at clojure.lang.LazySeq.seq(LazySeq.java:40)
        at clojure.lang.Cons.next(Cons.java:37)
        at clojure.lang.RT.count(RT.java:522)
        at clojure.lang.Cons.count(Cons.java:47)
        at clojure.lang.Compiler.analyze(Compiler.java:4008)
        ... 29 more
Caused by: java.lang.RuntimeException:
java.lang.IllegalArgumentException: Don't know how to create ISeq
from: Symbol
        at clojure.lang.LazySeq.seq(LazySeq.java:40)
        at clojure.lang.RT.seqFrom(RT.java:481)
        at clojure.lang.RT.seq(RT.java:451)
        at clojure.lang.LazySeq.seq(LazySeq.java:36)
        ... 33 more
Caused by: java.lang.IllegalArgumentException: Don't know how to
create ISeq from: Symbol
        at clojure.lang.RT.seqFrom(RT.java:494)
        at clojure.lang.RT.seq(RT.java:451)
        at clojure.core$seq__3046.invoke(core.clj:107)
        at clojure.core$concat__3174$cat__3188$fn__3189.invoke(core.clj:443)
        at clojure.lang.LazySeq.seq(LazySeq.java:36)
        ... 36 more

I've thrashed on a number of variations, none of which do much better.
I feel I'm missing something subtle here. What is the right approach?


-- 
Howard M. Lewis Ship

Creator Apache Tapestry and Apache HiveMind

--~--~---------~--~----~------------~-------~--~----~
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
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