Unit type?
John Rose
john.r.rose at oracle.com
Fri Sep 13 13:31:46 PDT 2013
On Sep 13, 2013, at 6:03 AM, Remi Forax <forax at univ-mlv.fr> wrote:
> On 09/13/2013 08:20 AM, Zhong Yu wrote:
>> Have you guys discussed about introducing Unit type in Java? What's
>> the thinking here?
>>
>> I'm looking at my code and I'm seeing a lot of `Foo<Void>`, `return
>> (Void)null`, or doubling APIs to handle both T->R and T->void cases.
>> This is becoming very ugly.
>>
>> While Void is a reasonable substitute for Unit in most use cases, it
>> doesn't feel right to pass 'null' around; it doesn't sound right that
>> a function yields a Void value.
>>
>> After lambda is released, people are going to desire a Unit type in
>> their functional style code more than before. Maybe Java8 should ship
>> with a Unit before it's too late? The current practice of using Void
>> for Unit is probably not too wide spread; we have a chance to correct
>> it now.
>>
>> If Java is determined to stick with Void down the road, can we at
>> least define a constant for (Void)null? Something like Void.VOID, so
>> that we can write `return VOID` and `x->VOID`.
>>
>> Zhong Yu
>>
>
> We discussed about allowing the compiler to insert 'return null' when
> the return type is Void,
> but because it was not a change related to lambda by itself, this item
> did not
> find its way to the final list.
>
> that's said it's a good feature for a coin2 project IMO.
Alas. This is an example of a design change that is so obviously correct and useful that nobody makes the change. Nobody does it because everybody says "that's so basic it can't be part of our task; it doesn't uniquely benefit us; it must be somebody else's job". In my experience, aligning inner class access rules in the JVM with the language is another example of this doomed minor enhancement.
FTR, more musings: The reason we have unit types is to formally express a normal return of zero bits or (equivalently) exactly one possible result. There's already a good way to describe this in Java, as a 'void' return. Adding another "unit" type would just get us into a new mess of unit conversions, which kill important things like spacecraft (http://mars.jpl.nasa.gov/msp98/news/mco990930.html).
Since null is the only possible value of a Void-typed reference, Void is an obviously reasonable type to express "only void, though I need a reference". The name correspondence is the same as between double and Double, int and (er) Integer. The unique Void value is a complete representation of the unique 'void' result. There are already automatic conversions between the unique Void value (null) and the 'void' return (non-)type. Method.reflect and MethodHandle.invoke both do this.
I think the main obstacle to this conversion is that the JLS is worded (unfortunately) in a way that resolutely denies the existence of unit types. Admitting that "void" is some sort of real return value (even of zero bits) would require large amounts of low-level wordsmithing in the JLS, in order to own up to the fact that "void" can be regarded as a (unit) type and can have a (unique) value.
The workaround is pretty simple: Continue to worry about "void" as a special case, and put in "return null" when the compiler forces you to. To me the sad part will be when I have to wrap a lambda body (x,y)->{f(x,y);return null;} around a member reference in order to insert the "return null" into the otherwise reasonable this::f.
Yes, this is a good coin2 proposal. And the coin initiative is an excellent way to combat the problem I'm moaning about. But, as a lumper (not a splitter) I lean towards rolling in Good Stuff earlier, rather than waiting for the exact right vehicle to come along.
— John
More information about the lambda-dev
mailing list