Clojure static typing
Asked Answered
V

6

25

I know that this may sound like blasphemy to Lisp aficionados (and other lovers of dynamic languages), but how difficult would it be to enhance the Clojure compiler to support static (compile-time) type checking?

Setting aside the arguments for and against static and dynamic typing, is this possible (not "is this advisable")?

I was thinking that adding a new reader macro to force a compile-time type (an enhanced version of the #^ macro) and adding the type information to the symbol table would allow the compiler to flag places where a variables was misused. For example, in the following code, I would expect a compile-time error (#* is the "compile-time" type macro):

(defn get-length [#*String s] (.length s))
(defn test-get-length [] (get-length 2.0))

The #^ macro could even be reused with a global variable (*compile-time-type-checking*) to force the compiler the do the checks.

Any thoughts on the feasibility?

Viera answered 15/11, 2010 at 13:10 Comment(3)
(definline t [] (list '.charAt "hello" (nth [1 "a" 2 :c 0] (rand-int 4))))Populace
+1 i really like to get some optional static type checking in clojure a la racket docs.racket-lang.org/ts-guide/beginning.htmlOutwash
Some Common Lisp compilers like SBCL are detecting some static type errors, like this one.Tawannatawdry
D
8

It's certainly possible. The compiler already does some static type checking around primitive argument types in the 1.3 development branch.

Depressant answered 15/11, 2010 at 13:47 Comment(4)
Its possible now somebody just needs to take the time to implement it but most people don't really care. (We would have to use the Java typesystem and that not really good in the first place)Pash
@nickik: Yeah, but as you well know, there are two kinds of programmers in the world: those who love dynamic typing and those who hate it. If Clojure had optional static typing, many of the "dynamic haters" could be induced to try it.Viera
The consensus I've heard is that it's not worth doing right now because the Clojure compiler is going to be rewritten in Clojure at some point.Anthocyanin
@Ralph: The static fans would still not like it because most code is not type safe and the type system sucks (thats what Haskell people say I don't really know if it is true)Pash
S
11

It certain possible. However I do not think that Clojure will ever get any form of weak static typing - it's benefits are too few.

Rich Hickey has however expressed on several occasions his like for the strong, optional, and expressive typing feature of the Qi language, http://www.lambdassociates.org/qilisp.htm

alt text

Spam answered 15/11, 2010 at 14:7 Comment(1)
Thanks David - do you have any references for Rich expressing this?Videlicet
D
8

It's certainly possible. The compiler already does some static type checking around primitive argument types in the 1.3 development branch.

Depressant answered 15/11, 2010 at 13:47 Comment(4)
Its possible now somebody just needs to take the time to implement it but most people don't really care. (We would have to use the Java typesystem and that not really good in the first place)Pash
@nickik: Yeah, but as you well know, there are two kinds of programmers in the world: those who love dynamic typing and those who hate it. If Clojure had optional static typing, many of the "dynamic haters" could be induced to try it.Viera
The consensus I've heard is that it's not worth doing right now because the Clojure compiler is going to be rewritten in Clojure at some point.Anthocyanin
@Ralph: The static fans would still not like it because most code is not type safe and the type system sucks (thats what Haskell people say I don't really know if it is true)Pash
E
8

Yes! It looks like there is a project underway, core.typed, to make optional static type checking a reality. See the Github project and its documentation

This work grew out of an undergraduate honours dissertation (PDF) by Ambrose Bonnaire-Sergeant, and is related to the Typed Racket system.

Exchequer answered 19/3, 2013 at 18:51 Comment(1)
I actually looked at this a few weeks ago. Hopefully it will fully mature.Viera
G
0

Since one form is read AND evaluated at a time you cannot have forward references making this somewhat limited.

Gallaher answered 15/11, 2010 at 13:30 Comment(5)
Clojure supports forward references w/ declare.Spam
Clojure supports forward references for "variables" which doesn't do any good for static type checking. You can't statically check a type you don't know about yet (except the name, you know nothing of data structure). This is why many statically typed languages have a two pass compiler. First build the symbol table and then check it. So what Stuart said is correct for types that are already defined (primitives, STD lib, etc including any classes you have defined up until this point in your program) but it is not a general solution.Gallaher
On declare, can there be type hints?Viera
I don't think that's necessary depending on how your type system is implemented. That's why I mentioned Qi.Spam
F# has no forward references, and that works just fine. It's actually nice, you always know how to read code. It does have 'and' though, which is forward checking for a limited scope.Aitchbone
G
0

declare can have type hints, so it is possible to declare a var that "is" the type which has not been defined yet but contains data about the structure, but this would be really clunky and you would have to do it before any code path that could be executed before the type is defined. Basically, you would want to define all of your user defined types up front and then use them like normal. I think that makes library writing somewhat hackish.

I didn't mean to suggest earlier that this isn't possible, just that for user defined types it is a lot more complicated than for pre-defined types. The benefit of doing this vs. the cost is something that should be seriously considered. But I encourage anyone who is interested to try it out and see if they can make it work!

Gallaher answered 15/11, 2010 at 15:30 Comment(2)
One of the great things about Clojure (and other Lisps) is the macro system. I agree that adding metadata to declare is clunky, but with a new macro (e.g.: declare-typed), adding the metadata could be very easy. Similarly for def.Viera
As dnolen pointed out on the other comment thread, you don't have to use a two pass type checking algorithm. That's why I used the word "many" and not all when describing statically typed languages.Gallaher
V
0

Old question but two important points: I don't think Clojure supports reader macros, only ordinary lisp macros. And now we have core.typed option for typing in Clojure.

Various answered 17/10, 2013 at 16:38 Comment(1)
Clojure does support reader macros, just not user-defined reader macros.Viera

© 2022 - 2024 — McMap. All rights reserved.