The soul of case

368 views
Skip to first unread message

Matching Socks

unread,
Jun 18, 2017, 7:56:49 AM6/18/17
to Clojure
In Clojure's case, a symbol is a symbol. For example, this snippet of Clojure says :no-match.

(ns foo.bar)

(def ^:const n 3)
(def ^:const m 4)

(let [x 4]
 
(case x
    n
1
    m
2
   
7 3
   
"hi" 4
   
:no-match))


The snippet came from http://blog.fikesfarm.com/posts/2015-06-15-clojurescript-case-constants.html, which uses it to illustrate a rip-snorting new feature of ClojureScript's version of the case form.  According to that page, --

in ClojureScript, the same case henceforth yields 2!

Is the same change coming to Clojure itself?

Alex Miller

unread,
Jun 18, 2017, 10:37:22 AM6/18/17
to Clojure
At a glance I'd say no and that seems wrong.

Herwig Hochleitner

unread,
Jun 18, 2017, 1:26:45 PM6/18/17
to clo...@googlegroups.com
I was pretty horrified, when this crossed my timeline. Thanks, Phil, for starting this thread, because I'd already forgotten about it.

First thing that seems strange, is, that the blog post is from 2015. Nevertheless, I just tried it on a nashorn repl:

cljs.user> *clojurescript-version*
"1.9.562"
cljs.user> (case 2
             x :X
             :no-match)
:no-match
cljs.user> (case 'x
             x :X
             :no-match)
:X
cljs.user> (def ^:const x 2)
#'cljs.user/x
cljs.user> (case 2
             x :X
             :no-match)
:X
cljs.user> (case 'x
             x :X
             :no-match)
:no-match

2017-06-18 16:37 GMT+02:00 Alex Miller <al...@puredanger.com>:
... that seems wrong.

Yes, yes it does.

David Nolen

unread,
Jun 18, 2017, 2:56:21 PM6/18/17
to clojure
I agree that this behavior diverges from Clojure's and that we probably should have thought it through a bit more 2 years ago. But at this point it's probably water under the bridge. Anybody that's actually relying on this behavior is likely inlining named numeric constants to make jump tables. The only semantic fuzzy area is if you want to match a symbol and you have defined a constant with the exact same symbol or referred such a constant in your namespace. But I suspect this requirement is esoteric enough that nobody has reported such a problem in actual code in the last 2 years.

I believe I accidentally let it slip through since I don't think I'd ever used `case` to match symbols myself and at the time I had not internalized that symbols need not be quoted in this case (yes I know it says so in the `case` docstring).

It's a strange historical quirk, but I also don't think the situation is interesting or common enough to be very worked up about :)

David

--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@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+unsubscribe@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Matching Socks

unread,
Jun 24, 2017, 1:49:09 PM6/24/17
to Clojure
Amusingly, ClojureScript's "case" works more like the way I always expect "case" to work.  A "case" in Clojure that did what I meant with Java public-static-final constants would be lovely, lovely.  ClojureScript's "case" is tasty candy!  

And now with cljc, those tasty "case" forms are going to migrate to Clojure and they are very quietly going to do something completely different.  That would be a bad thing and its taxonomic order would be "incidental complexity".

Maybe ClojureScript's super-charged "case" could move over to "case*"?

At any rate, I would like to put in either a documentation issue (if it's a feature that ClojureScript's "case" does not work like Clojure's) or else a defect issue (if it's a bug).  

In a way, this is a question of "easy" vs "simple".  Easy, to let ClojureScript accidentally differ (hey, it's better) and just document it.  Simple, to have one harmonious core language.

So I am inclined to put it in as a defect, even though I prefer ClojureScript's "case". 

Alex Miller

unread,
Jun 24, 2017, 4:07:15 PM6/24/17
to Clojure
Clojure's behavior is the intended behavior in Clojure.

I'll leave the choice of what to do in ClojureScript up to David.

Btw, I believe there actually is a case* in Clojure already which is part of the implementation details.

David Nolen

unread,
Jun 25, 2017, 6:53:49 PM6/25/17
to clojure
On Sat, Jun 24, 2017 at 1:49 PM, Matching Socks <phill...@gmail.com> wrote:

At any rate, I would like to put in either a documentation issue (if it's a feature that ClojureScript's "case" does not work like Clojure's) or else a defect issue (if it's a bug). 

As I stated earlier, we're not going to remove it nor change the existing behavior in anyway whatsoever. And yes it will get documented.

David

Adam Clements

unread,
Jun 26, 2017, 4:08:35 AM6/26/17
to clojure
This came up in 2014 on the mailing list https://groups.google.com/forum/m/#!topic/clojure/3yGjDO2YnjQ

And resulting enhancement requests Alex asked for:
https://dev.clojure.org/jira/browse/CLJ-1367
https://dev.clojure.org/jira/browse/CLJ-1368

For what it's worth (though I realise we don't want to break back compatibility), I find the clojure behavior v surprising given that the parallel switch/case in Java is so frequently used for exactly this sort of const jump table. Intuitively it makes no sense for me that in this one statement you would compare the symbol and not the const value. It actively discourages naming magic constants if you don't want to fall back to slower condp or a map lookup.

Adam


--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@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

For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages