Unit type?

Zhong Yu zhong.j.yu at gmail.com
Fri Sep 13 18:19:39 PDT 2013


On Fri, Sep 13, 2013 at 3:31 PM, John Rose <john.r.rose at oracle.com> wrote:
> 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.

Ok, Void is fine. But "return null" doesn't work in some cases because
javac needs to know the return type. And even if javac can inferred
the type, a human reader may not be able to. So we should always say
explicitly "return (Void)null". And we are going to need to do that a
lot from now on.

Could we have a constant for (Void)null please, so we can say "return
VOID"? I know any small API change to core lib is a bureaucratic
nightmare, but what could go wrong with a simple change like this?

public class Void

    /** a constant for (Void)null */
    public static final Void VOID = (Void)null;


>
> 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.

The workaround at this time is to declare "Void f()" instead of "void
f()". Maybe we should do that extensively for all new methods. And
maybe we can even do that for all existing "void" methods with
breaking anything.

The only downside (for now) is that the method body must contain a
"return (Void)null" in the end, which is pretty annoying if the body
is very short.


>
> 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