简体   繁体   中英

Why is Scala's Type system not a Library in Clojure

I've heard people claim that:

  • Scala's type system is amazing (existential types, variant, co-variant)

  • Because of the power of macros, everything is a library in Clojure: (pattern matching, logic programming, non-determinism, ..)

Question:

If both assertions are true, why is Scala's type system not a library in Clojure? Is it because:

  • types are one of these things that do not work well as a library? [ie the changes would somehow have to threaded through every existing clojure library, including clojure.core?]

  • is Scala's notion of types fundamentally incompatible with clojure protocol / records?

  • ... ?

It's an interesting question.

You are certainly right about Scala having an amazing type system, and about Clojure being phenomenal for meta-programming and extension of the language (although that is about more than just macros....).

A few reasons I can think of:

  1. Clojure is a dynamically typed language while Scala is a statically typed language. Having powerful type inference isn't so much use in a language where you can assume relatively little about the types of your inputs.
  2. Clojure already has a very interesting project to add typing as a library ( Typed Clojure ) which looks very promising - however it's very different in approach to Scala as it is designed for a dynamic language from the start (inspired more by Typed Racket , I believe).
  3. Clojure philosophy actually discourages certain OOP concepts (particularly implementation inheritance, mutable objects, and data encapsulation). A type system that supports these things (as Scala does) wouldn't be a good fit for Clojure idioms - at best they would be ignored, but they could easily encourage a style of development that would cause people to run into severe problems later.
  4. Clojure already provides tools that solve many of the problems you would typically solve with types in other languages - eg the use of protocols for polymorphism.
  5. There's a strong focus in the Clojure community on simplicity (in the sense of the excellent video "Simple Made Easy" - see particularly the slide at 39:30). While Scala's type system is certainly amazing, I think it's a stretch to describe it as "Simple"
  6. Putting in a Scala-style type system would probably require a complete rewrite of the Clojure compiler and make it substantially more complex. Nobody seems to have signed up so far to take on that particular challenge... and there's a risk that even if someone were willing and able to do this then the changes could be rejected for the various cultural / technical reasons covered above.

In the absence of a major change to Clojure itself (which I think would be unlikely) then one interesting possibility would be to create a DSL within Clojure that provided Scala-style type inference for a specific domain and compiled this DSL direct to optimised Java bytecode. I could see that being a useful approach for specific problem domains (large scale numerical data crunching with big matrices, for example).

To simply answer your question "... why is Scala's type system not a library in Clojure?":

Because the type system is part of the scala compiler and not of the scala library. The whole power of scalas type system only exists at compile time. The JVM has no support for things like that, because of type erasure and also, because it would simply slow down execution. And also there is no need for it. If you have a statically typed language, you don't need type information at runtime, unless you want to do dirty stuff.

edit:

@mikera the jvm is sure capable of running the scala compiler, I did not say anything like that. I just said, that the jvm has no support for type systems like that. It does not even support generics. At runtime all these types are gone. The compiler checks for the correctness of a program and removes all the higher kinded types / generics.

example:

val xs: List[Int] = List(1,2,3,4)
val x1: Int = xs.head

will at runtime look like this:

val xs: List = List.apply(1,2,3,4)
val x1: Int = xs.head.asInstanceOf[Int]

But it doesn't matter, because the compiler checked it before. You can only get in trouble here, when you use reflection, because you could put any value in the list and it would break at runtime exactly where the value is casted to Int .

And this is one of the reasons, why the scala type system is not part of the scala library, but built into the compiler.

And also the question of the OP was "... why is Scala's type system not a library in Clojure?" and not "Is it possible to create a type system such as scalas for clojure?" and I perfectly answered that question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM