Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clojure `case` doesn't differentiate different symbols

Tags:

case

clojure

This code works:

(case '-
    + :plus
    - :minus
    :unknown)
==> :minus

This too:

(case '-
    + :plus
    '- :minus
    * :times
    :unknown)
==> :minus

This doesn't:

(case '-
    '+ :plus
    '- :minus
    * :times
    :unknown)
==> java.lang.IllegalArgumentException: Duplicate case test constant: quote

Googling for this error leads to log file here. However, the guy just said it worked with quotes removed.

It looks like the case statement treats different symbols as the same value. Why is this so?

TIA.

like image 609
foresightyj Avatar asked Feb 02 '26 21:02

foresightyj


1 Answers

From the case documentation:

Each clause can take the form of either:

test-constant result-expr

(test-constant1 ... test-constantN)  result-expr

'- expands to (quote -).

Therefore, the clauses in the case with quotes expand to:

(quote -) :minus
(quote +) :plus

As you can see, the symbol "quote" appears as an actual test constant, and when you quote both + and -, it appears twice.

Evaluating the case on the actual symbol quote might clarify things:

user=> (case 'quote '+ :plus - :minus :unknown)
:plus
user=> (case 'foo (foo +) :plus - :minus :unknown)
:plus
like image 166
svk Avatar answered Feb 04 '26 14:02

svk