Wednesday, January 2, 2013

Types in Scala

Writing a toy program in Scala is turning out to be surprisingly difficult. I think I'm running into a something that makes Scala fundamentally different from many other languages I've programmed with: Scala types are surprisingly complex. I don't necessarily mean this in a negative way.

I've so far tried manipulating two types in my program: maps and streams. Maps can be mutable or immutable. The latter seems to be the default behavior. When I tried creating an immutable map from a mutable one, the compiler complained with an obscure message:

scala.collection.mutable.Map[String, String]().toMap()

type mismatch; found: scala.collection.immutable.Map[String,String]; required: <:<[(String, String),(String, String)]

The argument doesn't seem to be used in the implementation of toMap() though. Instead of chasing down this mystery, for my program, I have used Map.newBuilder, as has been used in toMap().

But now that I'm looking at this again, I notice that:
  1. I should have called scala.collection.mutable.Map[String, String]().toMap.
  2. The required argument is a generic transformer from the map elements (if the map is viewed as a collection of pairs) to map entries. This is a vacuous transformation. There's more information in this StackOverflow thread.
Streams seem fundamentally different data structures from Java streams. Looking through the API, I don't see any operations on scala streams analogous to the low level streams, such as file streams, that Java provides. I might have missed something. Otherwise, it would seem to me that Scala isn't really a "full" language, in that there are basic operations that it expects you to implement through Java. Perhaps this isn't that different from clojure either, which explicitly aims to be a hosted language.