Why does EK9 reject the ? modifier on function parameters?
← Code Quality · Ref: Q827
A parameter in EK9 is always PRESENT: the caller must pass something for it. So declaring a parameter with ? is not needed, and the compiler rejects it.
THE RULE
Parameters cannot use the ? modifier:
process()
-> input as String? // ERROR: E07300
<- rtn as String: input
THE FIX
Remove the ? modifier:
process()
-> input as String // CORRECT
<- rtn as String: input
PRESENT IS NOT THE SAME AS SET
E07300 is about the declaration, not the value. A caller may still pass an UNSET value - processInput(String()) runs the body with 'input' present but unset, and here the result comes back unset too (the program below prints 'Result set: false'). So the body must still treat a parameter as possibly unset, with a guard or the ? operator, when that matters.
WHY THIS MATTERS
EK9 pushes for everything to be initialised. A parameter can never be absent, so '?' on its declaration would be false optionality - the possibly-unset case is handled where the value is used.
See Q310 for code quality. See Q126 for function patterns.
Example
defines module qa.quality.null.not.needed defines function processInput() as pure -> input as String <- rtn as String: `Processed: ${input}` defines program NullNotNeededDemo() stdout <- Stdout() result <- processInput("hello") stdout.println(result) //A caller CAN pass an unset value: the parameter is present but unset missing <- String() fromUnset <- processInput(missing) stdout.println(`Result set: ${fromUnset?}`)
Common mistakes
E07300 — Function parameters are always provided by the caller, so they are never absent and the ? modifier is not allowed. Remove it - a caller may still pass an unset value, so check with ? or a guard where it matters. See ek9 -h E07300 for details.
Incorrect:
-> input as String?
Correct:
-> input as String
Other ways to ask this
- What is E07300 DECLARED_AS_NULL_NOT_NEEDED?
- Why can't I declare a parameter as potentially unset in EK9?
- How does EK9 enforce parameter initialisation?
Coming from another language?
Java: any reference parameter may be null; @Nullable/@NonNull are unenforced annotations. Kotlin: parameters can be nullable with ?. Rust: parameters are always initialised. Go: parameters always have zero values. EK9: parameters are always present — ? modifier not allowed (E07300) — but a caller may pass an unset value.
Keywords: initialised, optional, E07300, unset, null, parameter, declared