Why must generic types always be parameterized when used?

← Generics · Ref: Q948

List needs 'of String', Dict needs 'of (String, Integer)'. Can't use bare generic name.

EK9 requires all generic types to be fully parameterized when used. A bare generic name like 'List' or 'Dict' without type arguments triggers E04080.

CORRECT USAGE

  names <- List() of String
  mapping <- Dict() of (String, Integer)
  maybe <- Optional() of Float

INCORRECT USAGE (E04080)

  names <- List()          // ERROR: needs 'of String'
  mapping <- Dict()        // ERROR: needs 'of (K, V)'

WHY REQUIRED

Without type parameters, the compiler cannot verify type safety of elements added to or retrieved from the collection. Unlike Java's raw types, EK9 never allows unparameterized generics.

See Q654 for parameter count validation. See Q196 for multi-parameter generics. See Q642 for constructor inference.

Example

defines module qa.generics.paramsrequired

  defines program

    GenericParamsRequiredDemo()
      stdout <- Stdout()

      //Correctly parameterized generics
      names <- List() of String
      names += "Alice"
      names += "Bob"
      stdout.println(`Names count: ${length names}`)

      ages <- Dict() of (String, Integer)
      stdout.println(`Dict set: ${ages?}`)

      maybe <- Optional() of Float
      stdout.println(`Optional set: ${maybe?}`)

      //Constructor inference also works
      inferred <- List("one")
      stdout.println(`Inferred list count: ${length inferred}`)

Common mistakes

E06010 — Generic types must be parameterized. List requires 'of String' (or another type). Using a bare generic name without type parameters triggers E06010. See ek9 -h E06010 for details.

Incorrect:

names <- List()

Correct:

names <- List() of String
Other ways to ask this
  • What triggers E04080 PARAMETERIZATION_REQUIRED?
  • Why can't I use bare List without 'of String'?
  • How do I correctly use Dict with type parameters?

Coming from another language?

Java: raw types allowed but deprecated (List vs List<String>). Python: untyped collections common. Go: generics always parameterized (Go 1.18+). Rust: generics always parameterized. EK9: E04080 enforces parameterization, no raw types ever.

Keywords: parameterization, E04080, type, raw, required, generic, List, parameter, Dict