开发者

Advantages of Scala's type system

I am exploring the Scala language. One claim I often hear is that Scala has a stronger type system than Java. By this I think what people mean is that:

  • scalac rejects certain buggy programs which javac will compile happily, only to cause a runtime error.
  • Certain invariants can be encoded in a Scala program such that the co开发者_如何学Gompiler won't let the programmer write code that violates the condition.

Am I right in thinking so?


The main advantage of the Scala Type system is not so much being stronger but rather being far richer (see "The Scala Type System").
(Java can define some of them, and implement others, but Scala has them built-in).
See also The Myth Makers 1: Scala's "Type Types", commenting Steve Yegge's blog post, where he "disses" Scala as "Frankenstein's Monster" because "there are type types, and type type types".

  • Value type classes (useful for reasonably small data structures that have value semantics) used instead of primitives types (Int, Doubles, ...), with implicit conversion to "Rich" classes for additional methods.
  • Nonnullable type
  • Monad types
  • Trait types (and the mixin composition that comes with it)
  • Singleton object types (just define an 'object' and you have one),
  • Compound types (intersections of object types, to express that the type of an object is a subtype of several other types),
  • Functional types ((type1, …)=>returnType syntax),
  • Case classes (regular classes which export their constructor parameters and which provide a recursive decomposition mechanism via pattern matching),
  • Path-dependent types (Languages that let you nest types provide ways to refer to those type paths),
  • Anonymous types (for defining anonymous functions),
  • Self types (can be used for instance in Trait),
  • Type aliases, along with:
  • package object (introduced in 2.8)
  • Generic types (like Java), with a type parameter annotation mechanism to control the subtyping behavior of generic types,
    • Covariant generic types: The annotation +T declares type T to be used only in covariant positions. Stack[T] is a subtype of Stack[S] if T is a subtype of S.
    • Contravariant generic types: -T would declare T to be used only in contravariant positions.
  • Bounded generic types (even though Java supports some part of it),
  • Higher kinded types, which allow one to express more advanced type relationships than is possible with Java Generics,
  • Abstract types (the alternative to generic type),
  • Existential types (used in Scala like the Java wildcard type),
  • Implicit types (see "The awesomeness of Scala is implicit",
  • View bounded types, and
  • Structural types, for specifing a type by specifying characteristics of the desired type (duck typing).


The main safety problem with Java relates to variance. Basically, a programmer can use incorrect variance declarations that may result in exceptions being thrown at run-time in Java, while Scala will not allow it.

In fact, the very fact that Java's Array is co-variant is already a problem, since it allows incorrect code to be generated. For instance, as exemplified by sepp2k:

String[] strings = {"foo"};
Object[] objects = strings;
objects[0] = new Object();

Then, of course, there are raw types in Java, which allows all sort of things.

Also, though Scala has it as well, there's casting. Java API is rich in type casts, and there's no idiom like Scala's case x: X => // x is now safely cast. Sure, one case use instanceof to accomplish that, but there's no incentive to do it. In fact, Scala's asInstanceOf is intentionally verbose.

These are the things that make Scala's type system stronger. It is also much richer, as VonC shows.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜