Should Java have a unit type?
Brian Goetz
brian.goetz at oracle.com
Thu May 10 02:02:03 UTC 2018
When we complete the (long) arc of Valhalla, making void a real type
will be highly desirable (for example, Consumer<T> becomes a refinement
of Function<T,void>). But that's a ways off.
On 5/9/2018 9:40 PM, James Roper wrote:
> Hi all,
>
> I'm interested in opinions on whether Java should have a unit type. I
> apologise if this has already been discussed on this list before, I did
> search for it but didn't find anything.
>
> By unit type, I'm referring to a type that represents no value. When a
> Java method returns no value, void is used, however, void is not a type.
>
> java.lang.Void exists as a placeholder class for use in reflection, but it
> doesn't seem that it's meant to be used directly as a type.
>
> In spite of this, java.lang.Void is used in some places in the JDK as a
> type, for example, it's used by CompletionStage in methods such as
> thenAccept to represent an operation that can complete or fail in future
> but has no value:
>
> https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletionStage.html#thenAccept-java.util.function.Consumer-
>
> Working with it in this way is a little clunky and counter intuitive, Void
> is uninstantiable, so how can a CompletionStage<Void> ever be redeemed? The
> answer is, it gets redeemed with null. Are null and void the same thing?
> Apparently, according to this API, but they aren't really, null represents
> the absence of a value that could exist, and is treated as such in APIs
> like java.util.Optional, which is a different thing from no value.
>
> Now perhaps the use of Void in this way by CompletionStage means the horse
> has already bolted, and that now Void is a unit type with a singleton
> instance represented by null, by default.
>
> But in my opinion, it really isn't ideal. One issue is that it means any
> API that uses Void types won't play well with other APIs that don't accept
> nulls - a consequence of void and null being different things. A big one in
> this case is Reactive Streams, onNext does not accept null, so if you
> asynchronously map a reactive stream, and the asynchronous operation you do
> returns CompletionStage<Void> (this is actually a common thing to do, eg,
> if you're doing a sequence of operations, and the last one is a commit, it
> is becoming common practice for asynchronous commit methods to return
> CompletionStage<Void>), then you need to thenApply that CompletionStage to
> some other non null unit type before you can emit it to the stream.
>
> So it's my opinion that Java should have a unit type. This could be done by
> promoting Void to a unit type, not just a placeholder type, and giving it a
> singleton instance. That approach would mean existing uses of Void as a
> unit type would be source compatible, and can migrate to using the instance
> instead of null.
>
> Another approach would be to introduce a new type, perhaps java.lang.Unit.
> Both Scala and Kotlin have their own unit types, scala.Unit and kotlin.Unit
> respectively. Akka did something a little more interesting, it has two unit
> types, used to indicate two different intents, the first is NotUsed, which
> is used to indicate that a type parameter has no significant meaning, and
> the second is Done, which is used to indicate that a type parameter of this
> type indicates that whatever it represents has been completed successfully
> - this type is typically used in combination with CompletionStage, while
> NotUsed might be used in place of Void in PrivelegedAction, as described
> here:
>
> https://docs.oracle.com/javase/8/docs/technotes/guides/security/doprivileged.html
>
> Regards,
>
> James
>
More information about the core-libs-dev
mailing list