| > How do people who write Clojure deal with lack of type checking? Runtime asserts, typically. It ends up being somewhat less of an issue in practice than someone coming from Java or Kotlin would assume, I think, because clojure really only has a single datatype: a sprawling, immutable soup of nested maps and vectors. The design of the standard library is such that your standard data manipulation functions will basically always work on every data structure you get passed, so you end up designing your internal APIs so that they take in a blob of data, perform an operation if the soup has the right components (and probably throw an exception if not), and then spit out that changed blob of data. Is this better (or at minimum no worse) than having a type system? That's a broader question of philosophy and taste that I'm still undecided myself (for instance, I think the type systems in Haskell and Rust are really quite valuable, but the ones in Java and Go don't really pull their weight), but it's not something I really miss on a day-to-day basis writing clojure code--it's just a different way of doing things. > And auto-complete when it comes to Java library interop? My experience as both a professional and hobbyist clojure user is that this is not a huge issue in practice: - Java interop tends to get wrapped in clojure defns so you can get your auto-complete pop-up off the namespace alias. - At least with my setup (emacs+cider), adding a (:import (...)) clause to a ns form allows me to autocomplete on all method names of classes in scope (and provides type-annotated signatures), so I can still auto-complete when performing interop. I believe IntelliJ+cursive is even better about that sort of thing, and if I were working directly with Java libraries/APIs a lot I would probably consider switching IDEs for that reason. |