Hacker News new | ask | show | jobs
by neukoelln 3702 days ago
If you have your class extend AnyVal, you even get the wrapping for free.
1 comments

You should never extend AnyVal, unless you're using that for defining extension methods. The feature is a hack, because it has to workaround the JVM's lack of value classes, hence it has non-intuitive behavior and it probably doesn't work as you think it does.

In particular if you ever have to declare the type anywhere (or in other words, whenever you treat it as a type), like in:

     case class Person(id: PersonId)
That's going to be an allocated PersonId instance. And the limitations don't stop there. You'll also get instances allocated when doing pattern matching, or when working with generic functions. Heck, if you'll actually measure the performance, you'll soon discover that the JVM will allocate more on the heap and not less. And there goes the primary use-cases out the window. So you might as well have it as a normal class and avoid the gotchas and your colleagues cursing ;-)
I admit that I am not an expert on Scala, but I am confused about your "Person" example. I thought that this was exactly the common use case that wouldn't cost you an allocation. According to http://docs.scala-lang.org/overviews/core/value-classes.html:

    A value class is actually instantiated when:

        a value class is treated as another type.
        a value class is assigned to an array.
        doing runtime type tests, such as pattern matching.
none of which is the case in the example.
I disagree. Value classes are a great tool in my arsenal, and not just for extension methods.
Value classes solve this problem without the overhead of runtime allocation...