Void Variables and Fields¶
This README describes support for void
variables and class/record
fields. A variable or field with type void
will be removed from
the program by the compiler. It cannot be assigned to a variable of
any non-void type, and non-void values cannot be assigned to a void
variable. A void
variable cannot be used in any context that
requires a non-void value.
The value with type void
is currently named _void
. It is
expected that this name will be changed.
A void
value can be used to instantiate fully-generic function
arguments as long as the argument is not used in any non-void context.
This will cause the function argument to be removed by the compiler.
How is this useful?¶
Often a class or record will have different implementation strategies depending on things like the properties of the hardware or the type of a generic field. When the different implementation strategies each require their own class/record fields, the number of fields in the type grows, ballooning the size of the type with unused variables.
The type void
was introduced to allow the unused variables to be
removed by the compiler. For example, if some fields are used only
when the param isAccelerator
is true
, they can be declared
with a conditional type that is void
when it is false
. Such
fields will be removed by the compiler.
record R {
param isAccelerator: bool;
var accelVar: if isAccelerator then real else void;
proc doComputation() {
if isAccelerator {
... accelVar ...
} else {
// non-accelerator version
}
}
}
Void Functions¶
A function that does not return is treated as a function that returns a
void
value. A non-returning function can be assigned to a variable
of type void
. Initializing a variable without a specified type with
a function that doesn't return will infer the variable type to be
void
. The variables will be removed by the compiler.
A function may also explicitly return the void
value _void
.
Functions that have no return and functions that return the value _void
both have a return type of void
. Functions that have no return and
functions that return _void
can both optionally specify their return
types as void
.
proc noReturn(): void {
writeln("Hello from noReturn");
}
var v1: void = noReturn();
var v2 = noReturn();
proc explicitReturn(): void {
writeln("Hello from explicitReturn");
return _void;
}
var v3: void = explicitReturn();
var v4 = explicitReturn();
In the future, a function that does not return may be differentiated from
a function that explicitly returns a void
value. In that case, both
the v1
and v2
examples above would be errors, but a function that
returns a void
value explicitly would still be assignable to a variable
of type void
, as is the case for v3
and v4
.