Hacker News new | ask | show | jobs
by yummyfajitas 4532 days ago
Yes, and there is a good reason why Scalaland uses types. Consider a Spray-like API using only maps:

    val cookies = Map("sessionid" -> "1234567")
    val headers = Map("Content-Type" -> "application/javascript")

    setCookies(headers) {
      setHeaders(headers) {
        complete { obj }
      }
    }
With Scala's "make everything a different type" approach, that's a compile error - setCookies will expect a List[Cookie], not a List[HttpHeader].

Those of us living in Scalaland are not as smart as the Clojure guys. We make mistakes sometimes and find it handy when the compiler yells at us.

1 comments

This is actually a good example of something I don't like in Scala. They don't make this sort of differentiation easy enough. Adding a Haskell style newtype would be really, really useful.
Scala has value types.

    case class MyNewType(x: String) extends AnyVal
What do you want to do that that isn't sufficient for?
AnyVal's would probably be sufficient except for the following: - Instantiation of the MyNewType happens all the time and is not obvious from inspection of the code (generics, use as another type if we implement a trait, etc). - If we want to call any of the methods on the wrapped type we have to call directly to the wrapped type violating Demeter. - Verbosity.
If we want to call any of the methods on the wrapped type we have to call directly to the wrapped type violating Demeter.

You can also use tagged types:

http://eed3si9n.com/learning-scalaz/Tagged+type.html

But most of the methods will untag the type. I.e., ("foo" @@ ValidJsonString).substring(3,7) will be a String, not a String @@ ValidJsonString.

Unboxed tagged types to the rescue:

http://etorreborre.blogspot.co.uk/2011/11/practical-uses-for...

Scalaz implements this, so you can use it straight away. We use it mostly to control implicit selection.

Tagged types also have their problems.

1st they don't propagate, call a function on the tagged type and it returns the underlying type.

2nd they aren't type safe against the tagged type, so you can pass tagged types into functions that take the underlying type by default.

3rd in practice my code with tagged types ends up having lots of boilerplate and/or magic code that is hard to understand.

4th there are some pretty heinous compiler bugs that you will encounter with tagged types.

It seems you've done a lot more with them than I have. I'm looking forward to crashing the compiler -- the true badge of honour amongst Scala developers ;-)
They absolutely shouldn't propagate.

    val x = 1.0 @@ Kilograms
    val y = x*x
y is not a Double @@ Kilograms.
In many cases I'd like it to be.
Value classes make tagged types obsolete:

http://docs.scala-lang.org/overviews/core/value-classes.html

They still have uses for disambiguating implicits. There are at least four monoids for the Int: 0/+, 1/*, MinValue/Max, and MaxValue/Min. It is useful to tag them so one can specify which monoid one wants.