On Wed, Feb 24, 2010 at 8:57 PM, pthatcher <pthatc...@gmail.com> wrote:
> Ouch.  Burned by documented behavior :).  Thanks for pointing that
> out.
>
> Seriously, though, I'm not the last that will get confused by this.
> My suggestion would be to make (case) copy the value from the *var* at
> compile time and use that.

But eval at compile time is completely different than eval at
runtime, and not generally not useful.

> ; these now work:
> (def *abc* "ABC")
>
> (case-eval "ABC"
>  "ABC"
>    :abc)
>
> (case-eval "ABC"
>  *abc*
>    :abc)
>
> (case-eval "ABC"
>  (*abc*)
>    :abc)

Sure, but these don't:

(let [xyz "XYZ"] (case-eval "XYZ" xyz :xyz))
java.lang.RuntimeException: java.lang.RuntimeException:
java.lang.UnsupportedOperationException: Can't eval locals
(NO_SOURCE_FILE:36) (NO_SOURCE_FILE:36)


(def *xyz* "update later")
(defn xyz? [] (case-eval "XYZ" *xyz* :xyz))
(def *xyz* "XYZ")
(xyz?)
java.lang.IllegalArgumentException: No matching clause: XYZ (NO_SOURCE_FILE:0)

The first case fails because locals don't have values yet when
macros used in their scope are being expanded.

The second case fails because the var's value is inserted into
the expanded code before it's updated.

The implementation of 'case' is built around the test values
being constants, and when that's what you have offers excellent
performance.  If your test values are not known until runtime,
use 'if', 'cond', or 'condp'.

--Chouser
http://joyofclojure.com/

-- 
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