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