Should Java have a unit type? (original) (raw)
James Roper james at lightbend.com
Thu May 10 01:40:10 UTC 2018
- Previous message: JEP 306 Question
- Next message: Should Java have a unit type?
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
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:
Working with it in this way is a little clunky and counter intuitive, Void is uninstantiable, so how can a CompletionStage 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 (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), 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
-- James Roper Senior Octonaut
Lightbend <https://www.lightbend.com/> – Build reactive apps! Twitter: @jroper <https://twitter.com/jroper>
- Previous message: JEP 306 Question
- Next message: Should Java have a unit type?
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]