Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

On the other hand, the type system being very static and expressive, the compiler does the kind of work for which in other languages you'd need to run more specialized tools or to write more unit tests. When I'm doing time comparisons, I take into account the whole development workflow, that's why the compiler's speed doesn't bother me as is - I mean, what's slower, compiling code with Scala, or running unit tests in Ruby?

In Scala you get things like this:

     scala> Option(3) match { case Some(nr) => println(nr) }
     <console>:9: warning: match may not be exhaustive.
     It would fail on the following input: None
Or like this:

     val stillAMap: Map[String, String] = Map("hello" -> "world").map { 
       case (key, value) => (key, value + ", Alex") 
     }

     val iterOfInt: Iterable[Int] = Map("hello" -> "world").map { 
       case (key, value) => value.length
     }
And because immutable sequences are covariant, it has no problem in doing this (i.e. in Scala types usually have a natural flow, no need for explicit castings or shoving round pegs in square holes):

     val iterOfAny: Iterable[Any] = iterOfInt
Actually, traits can be used as tags, so say you wanted to model the states of a state-machine, instead of having something like this, which is error prone:

     trait Foo {
       def isOperational: Boolean
       def isDispatched: Boolean
     }

     object Available extends Foo {
       val isOperational = true
       val isDispatched = false
     }

     object RampUp extends Foo {
       val isOperational = true
       val isDispatched = true
     }

     object Fault extends Foo {
       val isOperational = false
       val isDispatched = false       
     }

     // ...
You could do this:

     trait Foo

     trait IsOperational extends Foo
     trait IsNotOperational extends Foo
     trait IsDispatched extends Foo
     trait IsNotDispatched extends Foo

     object Available extends IsOperational with IsNotDispatched
     object RampUp extends IsOperational with IsDispatched
     object Fault extends IsNotOperational with IsNotDispatched
     // ...
And then you could have a pattern matcher definition, for you know, convenience:

     object IsDispatched {
       def unapply(state: IsOperational) = state match {
         case ref: IsDispatched => Some(ref)
         case _ => None
       }
     }
Question: what would be the inferred return type of the above unapply function? That's right, it's Option[IsOperational with IsDispatched].

Basically Scala is the type of static language with which you can enforce correctness of the business logic with types. Yes, the compiler is slow, but it's slow because it does so much and IMHO, that's time well spent.

Now I also like dynamic languages and on the issue of static versus dynamic, I think David Pollak said it better than I could - static type systems work better if the shape of the data you're working with is well defined, whereas dynamic type systems work better if the shape of the data is not well defined. So usually people are on either side of this debate depending on what they are working on ;-)



Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: