Well, I'm still interested in the above questions, but now I realized that spec is even harder to extend, since s/keys doesn't even truly take a standard map of keys and vectors, the vector can have an `or` in it, which is a non standard or, so a default eval does not handle it properly.
Hopefully the next version of spec might make this easier. Maybe I wish spec followed the data > function > macro philosophy, and that took regular clojure datastructures instead of this custom DSL it currently uses. On Monday, 12 March 2018 20:06:43 UTC-7, Didier wrote: > > 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.