Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

are there advantages for using value class (without methods) vs type alias?

Tags:

scala

Let's say I have this ADT :

case class Person(id: String)
case class Kid(id: String, name: String)

I would like to represent the id field in more explicit and type safe way. I have two options

1. type alias

type PersonId = String
case class Person(id: PersonId)
case class Kid(id: String, name: PersonId)

2. value class

case class PersonId(id: String) extends AnyVal
case class Person(id: PersonId)
case class Kid(id: String, name: PersonId)

Which approach is more idiomatic? Are there any advantages of using value class in this case (no additional methods)?

like image 718
igx Avatar asked Feb 14 '17 19:02

igx


1 Answers

Type aliases are purely a syntactic convenience—in some cases they can make code cleaner or easier to refactor, but they don't provide any additional type safety. For example, suppose I've got some code like this:

type DegreesC = Double
type DegreesF = Double

def c2f(c: DegreesC): DegreesF = (c * 9.0 / 5.0) + 32

And a value representing the current temperature in Fahrenheit:

val currentTempInF = 62.0

The compiler is happy to let me pass this to my c2f method:

scala> c2f(currentTempInF)
res1: DegreesF = 143.6

Value classes give you more type safety without the runtime cost of an additional allocation for the case class (although there is still a syntactic cost):

case class DegreesC(value: Double) extends AnyVal
case class DegreesF(value: Double) extends AnyVal

def c2f(c: DegreesC): DegreesF = DegreesF((c.value * 9.0 / 5.0) + 32)

val currentTempInF = DegreesF(62.0)

And then:

scala> c2f(currentTempInF)
<console>:14: error: type mismatch;
 found   : DegreesF
 required: DegreesC
       c2f(currentTempInF)
           ^

Which you prefer is a matter of taste. Personally I think type aliases in Scala are often overused and oversold, but I also tend to avoid value classes because they have weird limitations and bugs, and the runtime performance benefits they offer often aren't that important to me. In any case I wouldn't say one approach or the other is more idiomatic (if anything I'd give that status to a plain, non-value class case class).

like image 182
Travis Brown Avatar answered Sep 24 '22 02:09

Travis Brown