I feel these have been asked many times, but no answers I could find was 
complete, or satisfactory.

1) How do you, within a macro, choose to evaluate an argument? So imagine I 
wanted a macro which had applicative order of evaluation? Not a macro that 
returns a function which will be evaluated in applicative order, but 
actually evaluating the argument inside the macro, to resolve its value, 
whether it be part of a local, a symbol pointing to a var inside a 
namespace, or a literal value?

I can only think of:

(defmacro applicative-order
  [& args]
  (map eval args))

This works with global vars (def and defn), and it works with literal 
values, but not with locals.

My intuition tells me there's just no way to use locals inside a macro, 
since the macro is expanded before the locals are created.

1.1) Is it true that this will always work with globals and literal values?

1.2) Is there a safer way then using eval, which would similarly work with 
globals as well as literal values?

2) How can I force evaluation of a function's return value?

My intuition was, since I want applicative order of evaluation, to just use 
a function, but a function will return the code unevaluated.

(defn applicative-order
  [& args]
  `(~@args))

This works with globals, locals and literal values, but it returns 
unevaluated code.

So I thought about:

(defn applicative-order
  [& args]
  (eval `(~@args)))

This works, and my intuition tells me its totally fine, apart that I want 
to be sure not to use it with input from a user/file/io.

2.1) Is there any other way then using eval to do this?

2.2) Is there anything problematic with using eval like this? Any caveats 
with eval apart from input safety? Like situation where its missing 
environment data and thus fails to work as expected?

REMARKS:

Now you might wonder why all this is needed, well it turns out if you want 
to compose a macro, it can be quite tricky, and something like the above 
helps. Which macro do I want to compose? Well, in my case, s/keys macro 
from clojure.spec. If I want to create a spec from a map as such:

(def foo {:req [::a ::b]})
(let [bar {:req [::x ::y]}]
  (s/combine-keys foo bar {:req [::baz]})

Thank You.

-- 
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
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to