What is the Void type in EK9?
← Advanced Type System · Ref: Q256
Void represents the concept of no return value in EK9. It is the implicit return type when a function or method has no return declaration (no <- line). You cannot instantiate Void, use it as a variable type, or use it as a generic type parameter.
IMPLICIT VOID
When a function or method omits the return declaration, its return type is Void:
greet()
-> name as String
stdout.println(name)
This function returns Void because there is no <- declaration. You cannot assign its result to a variable.
FUNCTIONS WITH RETURN VALUES
A function with a <- declaration has an explicit return type:
doubled()
-> n as Integer
<- rtn as Integer: n * 2
This function returns Integer, not Void.
VOID VS UNSET
These are fundamentally different concepts:
Void: the concept of a value does not apply at all. The function produces no result. Unset: an object exists but has no meaningful value yet. Integer() is an unset Integer.
A Void function cannot produce a result. An unset variable can later receive a value.
VOID RESTRICTIONS
Cannot instantiate: Void() is not valid Cannot declare variables: v as Void is not valid Cannot use as generic parameter: List of Void is not valid Cannot use in stream pipelines: mapping to Void is not valid Cannot assign result: result <- voidFunction() causes a compile error
Void's isSet always returns false because there is no value to be set.
WHY VOID EXISTS
Void gives the type system a way to represent the absence of a return type. Without Void, the compiler would need special-case handling for functions that return nothing. With Void as a type, the type system is uniform: every function has a return type, and Void is the type that means no result.
See Q29 for the unset concept and tri-state semantics. See Q49 for defining functions. See Q50 for function return values.
Example
defines module qa.advancedtypes.voidtype defines function <?- A function that returns nothing (Void). No <- declaration means Void return type. -?> greet() -> name as String stdout <- Stdout() stdout.println(`Hello, ${name}!`) <?- A function with an explicit return value. The <- declaration specifies the return type. -?> doubled() as pure -> n as Integer <- rtn as Integer: n * 2 <?- A pure function that formats a greeting. -?> formatGreeting() as pure -> name as String <- rtn as String: `Welcome, ${name}` defines program VoidTypeDemo() stdout <- Stdout() // Void function: just performs an action, no result greet("Steve") // Non-void function: returns a value result <- doubled(21) stdout.println(`Doubled: ${result}`) // Can use return value in expressions greeting <- formatGreeting("Alice") stdout.println(greeting) // The following would NOT compile: // badResult <- greet("Bob") // Error: cannot assign Void result to a variable
Common mistakes
E50060 — Stdout does not have a display() method. The correct method is println(). Calling a non-existent method triggers E50060 — method not resolved. See ek9 -h E50060 for details.
Incorrect:
stdout.display(`Doubled: ${result}`)
Correct:
stdout.println(`Doubled: ${result}`)
Other ways to ask this
- How do functions with no return value work in EK9?
- What happens when a function does not declare a return?
- Is Void a real type in EK9?
Coming from another language?
Java: void keyword (lowercase, not a type), Void class exists but rarely used directly. C#: void keyword, similar to Java. Python: functions without return implicitly return None (which IS a value). Rust: unit type () serves as void, IS a real type with one value. Go: functions without return type return nothing, no void keyword. Kotlin: Unit type (like Rust's unit), is a real singleton value. Swift: Void is a typealias for empty tuple (). EK9: Void is the implicit return type for functions without <- declaration, cannot be instantiated or used as variable type, distinct from unset.
Keywords: void, implicit, function, ok, type-system, type, restriction, return, result, method, declare, guard, unset, error, advanced