Вопрос

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.

Другие советы

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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top