Search code examples
scalaantcompiler-errorsfinal

Build and use custom scala-library to extend primitive datatypes


For a research prototype, I want to be able to extend primitive Scala datatypes (e.g., Double) with additional fields. This is not possible out-of-the-box because scala.Double and scala.runtime.RichDouble are declared final.

This is what I've tried:

  1. Clone the scala repository

  2. Remove the final modifier from class scala.runtime.RichDouble in file src/library/scala/runtime/RichDouble.scala

  3. Compile Scala using ant: ant build-opt

  4. Create a custom class extending RichDouble:

    $ echo "class MyDouble extends scala.runtime.RichDouble {}" > MyDouble.scala

  5. Compile MyDouble.scala using the custom-compiled scala:

    $ build/pack/bin/scalac MyDouble.scala

This, however, results in the following error:

MyDouble.scala:1: error: illegal inheritance from final class RichDouble class

Running with strace, the custom compiled scala-library.jar is indeed being loaded:

$ strace -f ./build/pack/bin/scalac MyDouble.scala 2>&1 | grep scala-library
stat("/my/custom/dir/scala/build/pack/lib/scala-library.jar", {st_mode=S_IFREG|0664, st_size=5682113, ...}) = 0

What am I missing? Why is class RichDouble still reported as final even though I removed the modifier?


Solution

  • What I was trying to do is not possible. Primitive types such as Double are implemented as value classes, which are implicitly final. As such, it is one of their essential limitations that they can not be extended.