Using an explicit eval is generally not a good idea, as `bar` will be evaluated at least twice: once in validating the precondition, and again in the macroexpansion. This can lead to all sorts of "interesting" problems if `bar` happens to be a side-effecting expression.
- Chas On Mar 20, 2012, at 9:18 AM, Daniel Solano Gomez wrote: > Hello, > > I am not sure that anything has changed between Clojure 1.2.1 and > Clojure 1.3.0 with respect to pre- and post-conditions. However, I > think I have any idea as to what may be going on. > > On Tue Mar 20 05:34 2012, Shantanu Kumar wrote: >> Hi, >> >> The way preconditions are invoked in Clojure 1.3.0 seems to have >> changed since Clojure 1.2: >> >> (defmacro foo >> [bar & body] >> {:pre [(string? bar)]} >> ...) >> >> (foo "bar34" ...) ; doesn't complain, which is OK >> (foo (str "baz" 34) ...) ; Error! (I wanted this to pass) > > As I understand it, as foo is a macro, bar isn't being evaluated in the > precondition. As a result it just gets whatever bar is. In the first > example, bar is "bar34", but in the second example, it's the list (str > "baz" 34). So, if you changed the precondition to (list? bar), the > first would fail, and the second would succeed. > >> When I write the precondition like this: >> >> {:pre [`(string? ~bar)]} >> >> It doesn't seem to check the precondition at all in 1.3.0. > > In this case, your precondition is evaluating to something like: > > (clojure.core/seq > (clojure.core/concat > (clojure.core/list (quote clojure.core/string?)) > (clojure.core/list bar))) > > And this does not evaluate to false. As such, the precondition is being > checked, it's just not checking what you want it to check. > > >> Can somebody suggest me what am I missing? I want both the examples >> above to be verified and passed as OK. > > I think what you may want is something like: > > {:pre [(string? (eval bar))]} > > However, I must question whether or not you really want to be doing > this. The precondition is being evaluated a compile/macro-expansion > time, not run time. As such, you should probably only use pre- and > post-conditions on defmacro if they are checking the arguments to the > macro itself. > > Just some thoughts. > > Sincerely, > > Daniel > -- 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