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.

Reply via email to