-
-
Notifications
You must be signed in to change notification settings - Fork 51
Comparison to Typed Clojure
a.k.a. core.typed
Clojure is a dynamically typed language, and no project is ever going to change that.
The best that Typed Clojure can offer is a means for individual programmers to annotate their own libraries with types, and sort-of monkey-patch foreign libraries (including Clojure's own libraries), in case they're missing typing information.
Unfortunately, this poses some issues.
One is that Clojure wasn't designed with types in mind, which means some of its functions, macros and other constructs don't play well with attempts to type them.
Typed Clojure, for instance, does not have a complete story when it comes to typing Clojure's libraries, with many functions missing annotations: https://github.com/clojure/core.typed/wiki/clojure.core-Annotations
Not only that, but because the typing is optional, and most Clojure programmers are fine with using dynamic types, the ecosystem is very dependent on the whims and needs of library providers, which often don't match the needs of library users who want types.
This forces library users to provide the types for the libraries they're consuming, instead of being able to just expect the types to be present (a practice that gets old rather quickly).
Community participation to expand the usage of core.typed is necessary, but lacking:
-
https://github.com/clojure/core.typed/wiki/Low-Hanging-Fruit
-
https://github.com/clojure/core.typed/wiki/Typed-Libraries
In contrast, Lux's type-system is a part of the language, and not subject to the whims of users.
There is an implicit contract between library providers and library consumers, that types will be present and that code will conform to the types, and won't deviate from expected behavior.
All Lux libraries are typed.
The type-system is a fundamental component of the compiler.
Types are even available to macros for the purpose of meta-programming.
In short, the type-system is not a hack.
Clojure's design is intimately coupled to the JVM, and Typed Clojure follows suit.
Because of that, Typed Clojure must have support for the kind of subtyping that goes on in object-oriented programming.
Lux's type-system is not dependent on any host platform, and does not support subtyping (since, in the future, Lux may be hosted by platforms which lack this).
Lux's type-checker does allow subtyping to play a part during the analysis of programs, to avoid flagging correct JVM programs as invalid.
However, there is no way to specify inheritance relationships or polymorphic bounds for type-variables in Lux.
With that said, even Typed Clojure has some issues when handling some of the intricacies of OO subtyping: https://github.com/clojure/core.typed/wiki/Accurate-downcasting
Higher-kinded types are an idea that some typed functional languages have adopted.
They are sort of a type-system on top of the type-system, and they allow you to impose some constraints on type-variables, in order to prevent invalid types from being constructed.
Typed Clojure has some support for this: https://github.com/clojure/core.typed/wiki/User-Guide#higher-kinded-variables
However, Lux doesn't implement higher-kinded types, as it was felt that the benefits they provided were not enough to justify the increase in complexity they would introduce.
Typed Clojure is an abstraction layer that exists on-top-of Clojure.
This is an important thing to consider, and one is often reminded about that when using the core.typed library.
For example, core.typed doesn't handle primitives properly: https://github.com/clojure/core.typed/wiki/Primitives
Also, core.typed's type-checker is not sophisticated enough as to properly understand Clojure's syntax and semantics.
This has led the Typed Clojure project to introduce a variety of alternative macros that are meant to be used instead of Clojure's own macros, in order to deal with the core.typed type-checker's limitations.
Typed Clojure needs extra assistance to understand functions: https://github.com/clojure/core.typed/wiki/User-Guide#functions
Typed Clojure needs extra assistance to understand protocols: https://github.com/clojure/core.typed/wiki/User-Guide#datatypes-and-protocols
Typed Clojure can't understand basic Clojure expressions (like loop
and for
):
https://github.com/clojure/core.typed/wiki/User-Guide#typed-wrapper-macros
On the other hand, Lux's type-system is intimately connected to the compiler, and the type-checker works properly with all Lux expressions.