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 [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
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
---
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 [email protected].
For more options, visit https://groups.google.com/d/optout.