How do function parameters work in EK9?

← Functions and Methods · Ref: Q597

EK9 function parameters use '->' for inputs and '<-' for the named return value. Parameters can be declared inline (single parameter) or in block style (multiple parameters).

SINGLE PARAMETER INLINE

For a single parameter, declare it directly after '->':

  greet()
    -> name as String
    <- message as String: "Hello, " + name

MULTIPLE PARAMETERS BLOCK STYLE

Multiple parameters are indented under '->':

  add() as pure
    ->
      a as Integer
      b as Integer
    <- result as Integer: a + b

RETURN VALUE

The return is declared with '<-' and a named variable. The compiler ensures all code paths initialise this variable. There is NO return statement in EK9.

SANITIZED PARAMETERS

The 'sanitized' keyword marks parameters that come from untrusted sources. The compiler copies the value through a sanitizing constructor:

  processInput()
    -> userInput as sanitized String
    <- cleaned as String: userInput.trim()

This prevents injection attacks at the language level.

ALL PARAMETERS MUST BE USED

The compiler errors (E08091) if a parameter is unused. Unused parameters are dead code: they increase signature complexity without contributing to the result. Abstract methods, overrides, and dispatchers are exempt from this check.

PARAMETER PASSING SEMANTICS

EK9 passes parameters by value for primitives and by reference for objects. Parameters are read-only by default in pure functions.

See Q49 for function basics. See Q54 for pure functions and Consumer vs Acceptor. See Q215 for sanitized parameters in depth. See Q319 for unused parameter detection. See Q596 for function vs method distinction. See Q598 for why EK9 has no default parameters. See Q599 for why EK9 has no varargs.

Example

defines module qa.functionsAndMethods.parameters

  defines function

    //Single parameter inline
    greet() as pure
      -> name as String
      <- message as String: `Hello, ${name}`

    //Multiple parameters block style
    add() as pure
      ->
        a as Integer
        b as Integer
      <- result as Integer: a + b

    //Return with body computation
    clampValue() as pure
      ->
        number as Integer
        minVal as Integer
        maxVal as Integer
      <- result as Integer: number
      if number < minVal
        result: minVal
      else if number > maxVal
        result: maxVal

    //Sanitized parameter for untrusted input
    cleanInput() as pure
      -> userInput as sanitized String
      <- cleaned as String: userInput.trim()

  defines program

    ParameterDemo()
      stdout <- Stdout()

      // === SINGLE PARAMETER ===
      stdout.println(greet("World"))

      // === MULTIPLE PARAMETERS ===
      stdout.println(`add(3, 4): ${add(3, 4)}`)

      // === RETURN WITH BODY ===
      stdout.println(`clamp(15, 0, 10): ${clampValue(15, 0, 10)}`)
      stdout.println(`clamp(-5, 0, 10): ${clampValue(-5, 0, 10)}`)
      stdout.println(`clamp(7, 0, 10): ${clampValue(7, 0, 10)}`)

      // === SANITIZED PARAMETER ===
      stdout.println(cleanInput("  trimmed  "))

Common mistakes

E01072 — EK9 has no return statement. Declare the return variable with a default and use if/else to modify it. See ek9 -h E01072 for details.

Incorrect:

if number < minVal
        return minVal
      else if number > maxVal
        return maxVal
      return number

Correct:

<- result as Integer: number
      if number < minVal
        result: minVal
      else if number > maxVal
        result: maxVal

E50060 — String has no toUpperCase() method in EK9. Use upperCase() instead. See ek9 -h E50060 for details.

Incorrect:

stdout.println(greet("World").toUpperCase())

Correct:

stdout.println(greet("World"))
Other ways to ask this
  • What are the parameter passing rules in EK9?
  • How do I declare function parameters in EK9?
  • What is the difference between inline and block parameters?

Coming from another language?

Java: parameters declared in parentheses, types before names, no named returns, return statement required, no sanitization keyword, unused parameters not flagged. Python: def func(a, b): with dynamic typing, *args and **kwargs for variable arguments, default values, no compile-time unused check. JavaScript: function(a, b) with no type safety, arguments object, rest parameters, no compile-time checks. Rust: fn func(a: i32, b: i32) -> i32, explicit return type, return keyword used, no sanitization. Go: func add(a, b int) int, explicit return type, return keyword. Kotlin: fun add(a: Int, b: Int): Int, default parameter values supported. EK9: '->' for parameters, '<-' for named return, no return statement, sanitized keyword for security, unused parameters are compile errors, block style for multiple parameters.

Keywords: block, migrate, input, parameter, side-effect, immutable, output, method, argument, sanitized, function, inline, pure, unused, style, return