How does EK9 detect when a function type or generic type is used incorrectly?
← Code Quality · Ref: Q742
EK9 validates type usage in two specific contexts.
TYPE MUST BE FUNCTION (E04040)
The 'call' and 'async' stream operators require function types. If you pipe non-function values (like integers or strings) into a call operation, the compiler rejects it. Only function references can be called.
NOT A TEMPLATE (E04070)
The 'of' syntax (e.g., List of String) is only valid for generic/template types. Applying type parameters to a non-generic type like Integer or a user-defined non-generic class is an error.
CORRECT PATTERNS
For stream call operations, ensure the pipeline contains function references. For generic types, only use 'of' with types designed to be parameterized (List, Dict, Optional, Result, etc.).
See Q707 for consumer/acceptor patterns. See Q642 for generic constructor inference.
Example
defines module qa.codequality.typefunctiongeneric defines function formatUpper() as pure -> text as String <- rtn as String: text.upperCase() formatBracket() as pure -> text as String <- rtn as String: `[${text}]` defines program TypeFunctionGenericDemo() stdout <- Stdout() //Correct use of generic types names <- List() of String names += "Alice" names += "Bob" stdout.println(`Names: ${length names}`) //Functions used correctly stdout.println(formatUpper("hello")) stdout.println(formatBracket("world"))
Common mistakes
E50060 — String has no getValue() method. formatUpper() already returns a String. See ek9 -h E50060 for details.
Incorrect:
stdout.println(formatUpper("hello").getValue())
Correct:
stdout.println(formatUpper("hello"))
E06010 — List is a generic type that requires a type parameter. Use 'List() of String' for explicit typing. See ek9 -h E06010 for details.
Incorrect:
names <- List()
Correct:
names <- List() of String
Other ways to ask this
- What is E04040 type must be function in EK9?
- What is E04070 not a template in EK9?
- Why does EK9 reject my stream call on a non-function type?
Coming from another language?
Java: type safety on generics via erasure, runtime ClassCastException possible. Python: no compile-time checking. Rust: trait bounds enforce generic constraints. Go: type parameters require interface constraints. EK9: compile-time enforcement of function types and generic type parameters.
Keywords: E04040, parameter, quality, call, E04070, stream, generic, function, type, template