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