Compile time parameters (constraining objects as well as types)

Instead of just passing known types to functions and constructors at compile time, if objects could be passed too, that could bring more safety to the program. Even if Scala doesn’t get variadic generics, it would still be really handy to have parameters that are checked at compile time inside of at runtime with require. For example, if value types could be part of a class’s generic signature, a few exceptions could be avoided, like in this class:

//length is of type Int and when put into the function _ >= 0, it must return true
class FixedSizeArr[val length: Int {_ >= 0}, T](val elems: T*) {
    def apply[val index: Int {_ >= 0, _ < length}]: T = elems(index)

And then,

val arr = new FixedSizeArr[5, String]("1", "2", "3","4", "5")

//should result in a compile time error
val fifth = arr[5]  
//no error here
val fifth = try {arr[5]} catch {case e: IllegalArgumentException => handle(e)}
//no error here either
val index = getIndex()
val fifth = if (index < arr.length && index > 0) arr[index] else "null"

With this, you wouldn’t get an exception saying the array index was out of bounds. The last one would require something like Kotlin’s smart casts, but the one before it, at least, would help, since Scala doesn’t have checked exceptions. Of course, it wouldn’t be possible to bound an object of just any type, since the compiler would have to run those functions itself, but value types could be used in generic signatures and they could be constrained by simple comparing operators, with something like asInstanceOf in case you don’t want to bother with checking if the value passed does not fit in the bounds. I’m not sure how this would be implemented, and the syntax in the examples is ugly, but it would be really nice having parameters checked at compile time.

1 Like

Maybe literal types and erased terms are related.


I gave a talk about this at the 2019 typelevel summit and how you can implement such stuff with the singleton-ops library. See: