For example, until recently ClojureScript's :keywords were just strings under the hood and it required a string compare to test equality. Apparently this is no longer the case due to this commit 2 months ago: https://github.com/clojure/clojurescript/commit/2cef52840fcd... but it shows you the kind of stuff you might run into. In a recent talk I saw by David Nolen, the lead maintainer of the ClojureScript compiler, he brought up multimethod dispatch as something that can still be as much as 100 times slower than the JVM.
As a tooling example, Clojure gives you helpful errors if you initialize records the wrong way:
user=> (defrecord Thing [foo bar])
user.Thing
user=> (Thing. 1 2) ; correct usage
#user.Thing{:foo 1, :bar 2}
user=> (Thing. 1) ; wrong number of fields
CompilerException java.lang.IllegalArgumentException: No matching ctor found for class user.Thing, compiling:(/tmp/form-init7089728177345913731.clj:1:1)
user=> (Thing 1 2) ; forgetting the dot
RuntimeException Expecting var, but Thing is mapped to class user.Thing clojure.lang.Util.runtimeException (Util.java:219)
That's good! Especially if you're new to the language. You see where you messed up right away.But ClojureScript just silently gives you nils:
ClojureScript:cljs.user> (defrecord Thing [foo bar])
cljs.user/Thing
ClojureScript:cljs.user> (Thing. 1 2) ; correct usage
#cljs.user.Thing{:foo 1, :bar 2}
ClojureScript:cljs.user> (Thing. 1) ; wrong number of fields
#cljs.user.Thing{:foo 1, :bar nil}
ClojureScript:cljs.user> (Thing 1 2) ; forgetting the dot
nil
This should be a bug report against the CLJS compiler (edit: now it is[1]), and it's probably not that hard to fix. I could fix it. You could fix it. (The CLJS compiler is very approachable and needs contributors, by the way.) But, especially as a newbie, this kind of stuff can bite you. JVM Clojure is more polished.