Robert Harper has written a fascinating piece called "Dynamic languages are static languages". In it he writes:
And this is precisely what is wrong with dynamically typed languages: rather than affording the freedom to ignore types, they instead impose the bondage of restricting attention to a single type! Every single value has to be a value of that type, you have no choice!
This has come to mean uni-typed languages. (Languages of a single type).
Now Clojure claims to be a dynamic language:
Clojure is a dynamic programming language that targets the Java Virtual Machine (and the CLR, and JavaScript). It is designed to be a general-purpose language, combining the approachability and interactive development of a scripting language with an efficient and robust infrastructure for multithreaded programming. Clojure is a compiled language - it compiles directly to JVM bytecode, yet remains completely dynamic. Every feature supported by Clojure is supported at runtime.
By 'dynamic' they mean 'can be interacted with at runtime', rather than 'doesn't have types'.
Now the key distinction being made between static and dynamic seems to be "can I get a type-failure at compile-time?"
If I write the following Clojure code:
(deftype circle-type [radius] )
(deftype square-type [side-length])
(defn def-check-type [new-symbol-type existing-symbol]
(let [existing-symbol-type (type existing-symbol)]
(cond
(= new-symbol-type existing-symbol-type)
(def new-symbol existing-symbol)
:else (str "types didn't match: " new-symbol-type " : " existing-symbol-type))))
(println (def-check-type circle-type (square-type. 2)));)
Then compile it in Leiningen:
lein uberjar
Then I get the following:
$ lein uberjar
Compiling clojure-unittyped.core
types didn't match: class clojure_unittyped.core.circle-type : class clojure_unittyped.core.square-type
Which would appear to be a type-failure at compile-time in a dynamic language.
My question is: Is Clojure Uni-Typed?
Edit - I'm aware of core.typed - which is an excellent piece of work. I'm asking the question separate to that.
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.