rybosome
rybosome

Reputation: 5136

What is Scala's "powerful" type system?

When Scala is discussed, the type system is always mentioned as one of the primary features. It is referred to as powerful, and the primary reason for the language moniker (Scala being short for "scalable language"). Could someone please explain how Scala typing works/why this unique, and how that contributes to the language being scalable?

Upvotes: 30

Views: 3171

Answers (5)

schmmd
schmmd

Reputation: 19468

A few advantages of Scala's type system over Java's:

  1. Types can be inferred in many cases, instead of being specified explicitly. This is more of a convenience, but it promotes using complicated types.

    val map = new Map[String, (String, String)]()

    instead of

    Map<String, Tuple<String, String>> map = new HashMap<String, Tuple<String, String>>()

  2. Functions can be expressed simply in the type system. If you want to see how powerful this is, consider the guava library as a work-around for Java . It's incredibly constrained and verbose (but still useful).

    val double = (x: Int) => x * 2

    instead of (using Guava)

    Function<Integer, Integer> double = new Function<Integer, Integer>() { @Override public Integer apply(Integer value) { return value * 2; }}

  3. Tuples are a type in Scala, circumventing Java's problem of only being able to return a single value.

  4. Scala supports type Variances so you can specify that SomeObject is a subtype of SomeObject when Cat is a subtype of Thing (or when the reverse relation holds). In java, generics are not covariant, which is often problematic.

  5. Scala supports a limited form of multiple-inheritence using traits. Unlike interfaces (of which multiple can be implemented in Java), traits can define methods and variables.

  6. Arrays are transparently handled like any other class.

  7. You can add methods to existing classes through implicit definitions. For example, you could add a "sum" method to Arrays of Integers.

    class IntArray(value: Array[Int]) { def sumIt = value.reduceRight(_+_) }
    implicit def pimpArray(xs: Array[Int]) = new IntArray(xs)
    Array(1,2,3).sumIt
    

This is another good resource for some of the above topics: http://www.codecommit.com/blog/scala/scala-for-java-refugees-part-5

Upvotes: 20

Daniel C. Sobral
Daniel C. Sobral

Reputation: 297245

I don't think the existing answers are appropriate. Scala has a lot of conveniences, but they are not related to the type system being powerful just because they relate to types. In fact, type inference is in direct conflict with the power of the type system -- were it less powerful, one could have full type inference (like in Haskell).

So,

  • Scala has classes with members. (Obvious, but I'm trying to be exhaustive here.)
  • Method ("def") members of a scala class can have zero or more parameter lists, each of which can have zero or more parameters, the last of which might be a vararg.
  • Parameters may be passed by value or by name.
  • Parameters have names and may have default values.
  • Scala has "var" and "val" members (which are, in practice, also methods).
  • Scala has "lazy val" members.
  • Scala has "type" members (type aliases), which may be specified as fixed types or as type boundaries.
  • Scala has abstract classes and members (all of the above members may be abstract).
  • Scala has inner class, traits and objects (Scala's inner class are different than Java's).
  • Scala's members, plus inner stuff, may be overriden.
  • Scala has type inheritance.
  • Scala has traits, providing multiple-inheritance with type linearization.
  • Scala's traits's method members may have abstract override (stackable, aspect-like override).
  • Scala has singleton types.
  • Scala has companion class/objects (related to scope).
  • Scala has private, protected and public scopes for classes, traits, singletons and members.
  • Scala's private and protected scopes can be limited to any enclosing package, class, trait or singleton, plus "this".
  • Scala has self types.
  • Scala has type parameters.
  • Scala's type parameters can be co- and contra-variant, as well as invariant.
  • Scala has type constructors.
  • Scala has higher-order types.
  • Scala has existential types.
  • Scala has structural types.
  • Scala has implicit parameters.
  • Scala has function types, though, since they are simply a class plus syntactic sugar, I don't think it belongs on this list. On the other hand, function types are part of view bounds, so maybe it does.
  • Scala has a top (like almost everyone) and a bottom (like other statically typed fp languages).
  • Scala's "unit" is a type with a value (as opposed to "void" elsewhere).

Next, there are features related to Scala's implicits, which is what merit their inclusion above.

  • Scala has view bounds, an implicit parameter that acts like another type bound.
  • Scala has context counds, an implicit parameter that acts like another bound.
  • Generally speaking, implicit parameters and type inference can be combined to construct arbitrary complex proofs over the type parameters.

Related to the last comment, implicits and type inference, together, make Scala's type system turing complete. That is, you codify arbitrary programs as types, that will be "run" at compile time by the compiler. Proof here, by way of SKI Calculus, with a "buggy" infinite loop in the types as further demonstration.

The list of features above is quite big and impressive on many points. It is, however, the way Scala combines implicits and type inference to produce static proofs at compile time (such as view bounds and context bounds) that make Scala's type system unique. AFAIK, there is no other language doing that, though there are certainly other languages providing proof capabilities through other means.

Upvotes: 46

Jesper Nordenberg
Jesper Nordenberg

Reputation: 2104

Any type system in which you can encode HList, TList and HOF for types is quite powerful IMHO. See http://apocalisp.wordpress.com/2010/06/08/type-level-programming-in-scala/ for more information.

Upvotes: 3

Landei
Landei

Reputation: 54584

In addition to schmmd's excellent answer, Scala's type system has even more important features:

  • objects are a clean alternative to static member variables and methods in Java, e.g. an object has it's own type and can be passed as argument
  • type declarations: you can define aliases for complicated types, like type FactorMap[A] = Map[A, Set[Int]]
  • abstract type members as alternative to generic-style types
  • self types
  • structural types
  • multiple argument lists for currying
  • implicit parameters and conversions, together with view bounds. This leads to the "pimp my library" pattern and can be used to simulate Haskell-style typeclasses
  • higher order types

The last point is one of my favorites. E.g. you can't write a simple general functor interface in Java. You would need...

public interface Function<A,B> {
   public B apply(A a);
}

//not valid Java
public interface Functor<C> {
   public <A,B> C<B> map(Function<A,B> fn, C<A> ca);
}

It works if you substitute some concrete type like List instead of C. In Java you can abstract over the content of a containter (e.g. by writing `List), but you can't abstract over the container itself. Trust me, I tried to find loopholes (the result was this). In Scala it's a breeze:

trait Functor[C[_]] {
   def map[A,B](fn: A => B, ca: C[A]):C[B]
}

object ListFunctor extends Functor[List] {
   def map[A,B](fn: A => B, ca: List[A]):List[B] = ca.map(fn)
}

Upvotes: 6

soc
soc

Reputation: 28433

I don't know if you know Java, but imagine Scala's type system like this:

  • Remove Java's artificial limitations of what you can do with types and generics
  • Add the common features of functional languages to it
  • Innovate on the oop/inheritance front

i would love o wrie more, bu my keyboard jus broke, sorry!

Upvotes: 0

Related Questions