Add isJS, isJVM, and isNative inline methods to scala.util.Properties

scala.util.Properties already has methods isWin and isMac, but no way to tell if Scala is running on the JVM, JS, or Native platforms.

This information is pretty important in applications like Scala 3’s Typeclass Derivation.

For example, imagine you have a Scala 3 crossproject with a /jvm, /js, and /shared folder.

In /shared, you define all your case class DTOs.

For JSON serialization, you pull in a new library and add derives JsonCodec to your classes.

It’s critical for this typeclass to know the environment. If JS, then it might use the global JSON object, and likewise on the JVM use some standard library method not-implemented by Scala.js.

The proposal is to add methods Properties.isJS, Properties.isJVM, and Properties.isNative, or something of similar effect. Since the methods will be inline, JsonCodec and other libraries can do inline ifs on the values and return a correct implementation.

The alternative that we’re living with is to define two different typeclasses, JsonCodecJVM and JsonCodecJS, and manually derive givens in objects in their respective projects, like

// in /shared project
case class User(name: String, isAdmin: Boolean, age: Int)

// in /js project
object DtoConverters:
  given JsonCodecJVM[User] = JsonCodecJVM.derived

// in /jvm project
object DtoConverters:
  given JsonCodecJS[User] = JsonCodecJS.derived

I vaguely remember @japgolly had some idea like this before. I wonder about the build-system implications for this, and also if there are other alternatives.

7 Likes