Is Clojure Uni-Typed?
Yes, Clojure is uni-typed, however Sam Tobin-Hochstadt argues the uni-typed classification is not very informative in practice.
The uni-typed theory reveals little about the nature of programming in a dynamically typed language; it's mainly useful for justifying the existence of "dynamic" types in type theory.
Projects like Typed Racket were invented precisely to discover and model the implicit type information utilised by programmers in such languages. Often types are quite accurate, and shows there's a lot more going on than meets the eye.
I read it. I don't get it. But, as the author Robert Harper guesses, I didn't go to Carnegie Mellon. We seem to have a bunch of vitriol directed at straw men followed eventually by what amounts to the startling conclusion that dynamically typed languages are dynamically typed.
The main confusion here is between the terms "dynamic programming language" and "dynamically typed". These are not the same thing. A dynamic programming language can have a robust static type system for example, even though most do not. Harper is perpetuating this confusion by mixing terms.
Dynamic languages
The description of Clojure that you quoted is about Clojure being a "dynamic programming language".
Every feature supported by Clojure is supported at runtime.
The point is that the full power of Clojure is available at runtime. You can add new code, add new types, extend protocols to existing types, etc., all dynamically at runtime.
This is worth bragging about.
So, when Harper asks sarcastically, "So, hey, dynamic languages are cool, right?", I answer sincerely, "Yes, sir, they are, but apparently we aren't talking about the same thing!".
Dynamic types
Dynamically typed vs. statically typed is a whole other issue. Clojure is not bragging about not having a robust type system. Most Clojurians would welcome the option, hence the interest in core.typed. There is a lot to be said for the type system of Haskell for example. No one is really challenging that.
Your example
In your example, you are blurring run-time with compile-time (which is already blurry with a dynamic language in which the full power of the compiler is available at runtime). The type checking you did occurs at the run-time of your println
statement. In Clojure, values have types, the storage location of reference types (such as var
you created with def
) do not.
Your question
To answer your title question, Clojure falls under the heading of dynamically typed. You can call dynamically typed "uni-typed" if you really want to; but, at least in the context of that article, it looks like that term is being used as a pejorative. Just call it dynamically typed, we know what that means.
The bigger issue though is that if you are focusing on dynamically vs statically typed, you are missing the, yes, totally cool, point of Clojure being a dynamic programming language. Projects like core.typed will eventually provide the typing. The cool parts will remain.