Empty value types
Paul Govereau
paul.govereau at oracle.com
Tue Aug 5 18:56:28 UTC 2014
Ok, that makes sense. You are saying we should treat what I was calling
an "empty value type" as a unit type instead. That is, a type with
exactly one member, and not a void type like I was thinking (which has
zero members). Also, if we think about value types in general as named
tuples, then the empty tuple is naturally a unit.
This raises another question though: what about void? There are several
uses of the type java.lang.Void in the libraries. The way I read these,
what is wanted is an analog of "void": that is, a truly empty type, not
a unit type (otherwise it would be called java.lang.Unit?). Given this,
should we have a way to declare analogs of "void"?
final __ByValue class LikeUnit { }
final __ByValue class LikeInt { int x; }
final __ByValue class LikeVoid { ????? }
Relatedly, is this a valid declaration:
final __ByValue V<T extends V<T>> { T t; }
and what is its relation to LikeVoid given that T is provably empty (has
no members)?
Another related question is: can we instantiate generic types with
"void"? e.g.
class F implements Function<int,void> {
void apply(int x) { ... }
}
and,
Set<void> one;
In some sense, we are promoting the primitive types up to being
first-class citizens in the language: they can be user defined as value
types, used in generics, etc. Is void coming along for the ride?
My guess is no, the examples above are all illegal: void has no
user-defined analogs, values can't be parametrized by empty types, and
void can't be used to instantiate a generic type. Is this right, or do
we want to think about making void a first-class citizen along with int,
etc.?
Paul
PS: In other languages we can see first-class void types, like:
type Void
type Unit = ()
type Option a = Some a | None
type AnotherUnit = Option Void
However, the language must guarantee that no value of a void type can
ever appear in a term.
On 08/05/2014 01:04 AM, John Rose wrote:
> Empty value types are perfectly reasonable to instantiate, although there is only one value of each such type (1 = 2^0).
>
> A type Set<T> can be efficiently implemented as Map<T,Unit>, if Unit is an empty value type which is instantiated for each set element.
>
> It is true that static members of empty types are not interestingly different from non static members. But I don't see a reason to forbid one or the other. If the type implements an interface it needs non static methods. Factories are static. Seems we need both even for the empties.
>
> Lots of types in FP langs use a unit type, and corresponding unit values, at least for arrow types. Am I missing something here?
>
> – John
>
>> On Aug 1, 2014, at 10:05 AM, Paul Govereau <paul.govereau at oracle.com> wrote:
>>
>> I don't think there is anything wrong with it. I can even think of a use case: phantom types.
>>
>> final __ByValue class ReadWrite {}
>> final __ByValue class ReadOnly {}
>> final __ByValue class File<T> { ... }
>>
>> File<ReadWrite> openForWrite(String file) { ... }
>> File<ReadOnly> openForRead(String file) { ... }
>>
>> void write(File<ReadWrite> file, ...) { ... }
>>
>> However, I think we need to add checks to detect construction of empty value types. I am not sure what to do about methods defined inside of an empty type? Maybe only static methods are OK?
>>
>> Paul
>>
>>> On 08/01/2014 12:50 PM, Brian Goetz wrote:
>>> While an empty value is silly, is there something actually wrong with it?
>>>
>>> Sent from my iPhone
>>>
>>>> On Aug 1, 2014, at 9:47 AM, Paul Govereau <paul.govereau at oracle.com> wrote:
>>>>
>>>> What are we going to do with empty value types?
>>>>
>>>> The most sensible thing seems to allow them to be declared but not constructed. e.g.
>>>>
>>>> final __ByValue class Void {} // <- ok
>>>>
>>>> Void v = __Make Void(); // <- error cannot construct empty type.
>>>>
>>>> Paul
More information about the valhalla-dev
mailing list