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. In fact, I decided to do just that and
created (case-eval). I hope it's useful to others also:
(defn count-from [start]
(iterate inc start))
; like python
(defn zip [& lists]
(apply map vector lists))
; like python
(defn enumerate [vals]
(zip (count-from 0) vals))
(defn map-when-index [p? f vals]
(for [[index val] (enumerate vals)]
(if (p? index)
(f val)
val)))
(defn eval-all [val]
(if (seq? val)
(map eval val)
(eval val)))
;evals the test cases
(defmacro case-eval [e & clauses]
`(case ~e ~@(map-when-index even? eval-all clauses)))
; these now work:
(def *abc* "ABC")
(case-eval "ABC"
"ABC"
:abc)
(case-eval "ABC"
*abc*
:abc)
(case-eval "ABC"
(*abc*)
:abc)
Find the full code here:
http://gist.github.com/314129
On Feb 23, 10:10 pm, Chouser <[email protected]> wrote:
> On Feb 23, 2010, at 8:47 PM, pthatcher <[email protected]> wrote:
>
> > I noticed a funny bug in Clojure 1.2's case macro. It doesn't work
> > with *vars*. For example:
>
> > (def *a* "a")
>
> > ;this is true
> > (case "a"
> > "a" true
> > false)
>
> > ;but this is false!
> > (case "a"
> > *a* true
> > false)
>
> If you read the first line or two of the docs for case I think you'll
> see it's not a bug but documented behavior. The values in the case
> test clauses must be constants, so not a var or local. If you need
> those test values to be evaluated then your "work around" of using
> condp (or cond) is entirely appropriate.
>
> --chouser
--
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