This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
- # announcements (1)
- # babashka (132)
- # beginners (52)
- # calva (46)
- # clj-kondo (8)
- # cljdoc (17)
- # clojure (13)
- # clojure-australia (1)
- # clojure-dev (3)
- # clojure-europe (4)
- # clojurescript (4)
- # cloverage (1)
- # conjure (22)
- # datomic (9)
- # emacs (2)
- # fulcro (16)
- # leiningen (5)
- # malli (26)
- # off-topic (16)
- # pathom (3)
- # portal (5)
- # reagent (10)
- # reitit (5)
- # rewrite-clj (1)
- # ring (1)
- # shadow-cljs (14)
- # spacemacs (6)
- # tools-deps (10)
- # vim (11)
- # vscode (1)
- # xtdb (10)
@kumarshantanu I'm pretty sure it's a bug because
cljs.core/const? does a pretty sloppy check to see if something is a constant or not.
To get more into the details.
Every list gets unwound inside the
case macro. Your
(()) becomes just
() (note that when you use
() instead of
(()), it will be removed completely).
Every symbol in the test parts of the clauses becomes
(quote symbol-name) inside the macro.
So if you use something like
(case a (()) 1 (x y) 2) it would essentially be (if the bug wasn't there) as if you used
(cond (= a ()) 1 (or (= a (quote x)) (= a (quote y))) 2 :else (throw ...))
case, whenever it sees a list inside already expanded test parts, assumes that it might be that
(quote symbol-name). It then checks whether
symbol-nameis actually a constant that can be inlined. The
(and (list? x) (analyzer/resolve-var (last x))). When
(quote symbol-name), all works just as intended. When
xis something else, it might break. Like in the case of
(analyzer/resolve-var nil)throws that NPE that you see.
With that being said, you can reproduce it with just
(case 1 (()) 1). If you put anything inside the innermost list that ends not with a symbol but with something that breaks
cljs.analyzer/resolve-var (a number, a string, another list, etc), it will break as well, just the exception will be different.