Why does EK9 reject 'of TypeName' on a non-generic type like String?
← Generics · Ref: Q1309
The 'of' clause supplies type arguments and is only valid on generic (template) types - those declared with 'of type T'. Applying 'of SomeType' to a non-generic type such as String, Integer or any plain class raises E04070 because the type has a fixed structure and has no type parameter to fill.
GENERIC TYPES (accept 'of')
Built-in: List of T, Dict of (K, V), Optional of T, Result of (OK, ERR).
User-defined: any class declared 'Container of type T'.
NON-GENERIC TYPES (reject 'of')
String, Integer, Float, Boolean, Character and any plain class without an 'of type T' declaration. These need no type argument, so an 'of' clause is meaningless.
FIX
Drop the 'of' clause for a non-generic type (just String()), or, if you need a parameterized container, use a generic type such as List() of String.
The opposite mistake - omitting 'of' on a generic type - raises E04080, and supplying the wrong number of type arguments raises E06020.
See Q194 for defining generic classes. See Q198 for built-in generics.
Example
defines module qa.generics.nongeneric defines program NonGenericOfDemo() stdout <- Stdout() // === CORRECT: 'of' on a GENERIC type === // List is declared 'of type T', so it accepts a type argument. names <- List() of String names += "Alice" names += "Bob" stdout.println(`List of String has ${length names} items`) // === CORRECT: a non-generic type needs NO 'of' clause === // String has a fixed structure; constructing it takes no type argument. greeting <- String("hello") stdout.println(`Plain String: ${greeting}`) // === WRONG (commented out): 'of' on a non-generic type === // bad <- String() of Integer // ERROR E04070: String is not generic stdout.println("Use 'of' only on generic types like List, Dict, Optional")
Common mistakes
E04070 — String is not a generic/template type, so it has no type parameter to fill - applying 'of Integer' to it raises E04070. Either drop the 'of' clause for the non-generic type (just String()), or use a genuinely generic type such as List() of String when you need a parameterized container. See ek9 -h E04070 for details.
Incorrect:
names <- String() of Integer
Correct:
names <- List() of String
Other ways to ask this
- What triggers E04070 when using 'of' on a type?
- Why can't I write String() of Integer in EK9?
- How do I know which types accept an 'of' clause in EK9?
Coming from another language?
Java: String<Integer> is a compile error too, but only because String is not declared generic - the message is 'type String does not take parameters'. C#: same, 'non-generic type cannot be used with type arguments'. Kotlin/Swift: angle-bracket arguments on a non-generic type are rejected by the parser/type checker. EK9: the 'of' clause is rejected at the EXPLICIT_TYPE_SYMBOL_DEFINITION phase with E04070, stating the type is not 'template/generic' in nature.
Keywords: String, parameter, of, List, E04070, non-generic, generic, type, parameterize, template