scala/scala-java8-compat

create a shared UNIT abstraction

rkuhn opened this issue · 7 comments

rkuhn commented

Akka Streams presents an interesting challenge in terms of creating an idiomatic API for both Scala and Java when it comes to a detail that is called “materialized values”. Every stream processing graph is associated with such a value computation and the value’s type is part of the graph’s type parameters:

trait Graph[+S <: Shape, +M] { ... }

M is the type of materialized value. Many graphs do not provide a materialized value, for which we are currently using Unit, which works well for Scala but is rather ugly and unfamiliar to Java users:

import scala.runtime.BoxedUnit
...
final Source<String, BoxedUnit> words = Source.from(Arrays.asList("Hello", "world!"));

BoxedUnit is a weird type that has no documentation and Scala in the package name, but we are providing a pure and separate Java DSL—this is not good enough.

Unfortunately the JDK itself does not offer a solution to this dilemma, using Void as the type (and null as the singleton value) is impossible due to null not being permitted in many relevant places, e.g. Optional<Void> throws NPE when actually used.

Therefore we need a place where the following class can live:

/**
 * Carefully documented.
 */
sealed abstract class UNIT
object UNIT extends UNIT {
  def instance: UNIT = this
}

It will be used for Akka Streams & HTTP (and then elsewhere in Akka) but it is potentially more widely useful. It is not so much about Scala–Java compatibility, but it is for libraries that want to present APIs in both of these languages.

What do others think about putting it in this project, within a nice non-scala package name? E.g. unit.UNIT?

I'd suggest not having an ALL_CAPS typename and making the constructor of the abstract class package-private.

rkuhn commented

Let’s leave implementation details aside for now (like constructor access) and concentrate on the place and name. We clearly cannot use Unit or Void, these are taken. Another constraint is that the type name should be rather short, the shorter the better. What about N_A for “not applicable”?

It might sounds cheesy, but what about "OK"?

rkuhn commented

Let’s wait for others to chime in (yes OK would work for me as well, but this issue is also about where to put the whole thing).

I ask this before akka/akka#18422

I think this is out of scope for this module, which is about bridging Java 8 with Scala.

rkuhn commented

This has been done in Akka now.