Thanks everybody for the pointers! I realized I was wrong about the
behavior being different in 1.2; rather it is the same since 1.1.0.

Shantanu

On Mar 20, 2:29 pm, Chas Emerick <c...@cemerick.com> wrote:
> 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

Reply via email to