Until recently (2023), the type inference was very weak and did not work with higher-order functions (map, filter, reduce, etc.).
As a result, Typed Clojure was practically unusable for most applications. That has changed as of last year. For instance, the type checker can now handle the following kinds of expressions.
(let [f (comp (fn [y] y)
(fn [x] x))]
(f 1))
This expression was a type error before early 2023, but now it is inferred as a value of type (Val 1).
Unfortunately, many Clojure users think types are somehow a bad thing and will usually repeat something from Rich Hickey's "Maybe Not" talk.
I've worked with Clojure professionally. The codebases I've seen work around dynamic types by aggressively spec'ing functions and enabling spec instrumentation in development builds. Of course, this instrumentation had to be disabled in production because spec validation has measurable overhead.
Although Typed Clojure has made remarkable progress, the most editor tooling I recall for Typed Clojure is an extension to CIDER that hasn't been maintained for several years. (The common excuse given in the Clojure community is that some software is "complete" thus doesn't need updates, but I have regularly found bugs in "complete" Clojure libraries, so I don't have much confidence here).
Overall, if one wants static typing, then Clojure will disappoint. I still use Clojure for small, personal-use tools. Having maintained large Clojure codebases, however, I no longer think the DX (and fearless refactoring) in languages like Rust and TypeScript is worth trading off.
As a result, Typed Clojure was practically unusable for most applications. That has changed as of last year. For instance, the type checker can now handle the following kinds of expressions.
This expression was a type error before early 2023, but now it is inferred as a value of type (Val 1).Unfortunately, many Clojure users think types are somehow a bad thing and will usually repeat something from Rich Hickey's "Maybe Not" talk.
I've worked with Clojure professionally. The codebases I've seen work around dynamic types by aggressively spec'ing functions and enabling spec instrumentation in development builds. Of course, this instrumentation had to be disabled in production because spec validation has measurable overhead.
Although Typed Clojure has made remarkable progress, the most editor tooling I recall for Typed Clojure is an extension to CIDER that hasn't been maintained for several years. (The common excuse given in the Clojure community is that some software is "complete" thus doesn't need updates, but I have regularly found bugs in "complete" Clojure libraries, so I don't have much confidence here).
Overall, if one wants static typing, then Clojure will disappoint. I still use Clojure for small, personal-use tools. Having maintained large Clojure codebases, however, I no longer think the DX (and fearless refactoring) in languages like Rust and TypeScript is worth trading off.