What can I name the type parameters of a generic type or function?
← Variable Naming Rules and Conventions · Ref: Q1390
A type parameter is a placeholder, so its name must not resolve to anything that already exists - not a built-in type, not one of your own classes or functions (even one declared later in the file), not a constant. Use a conceptual name: T, K, V, or a descriptive one such as Element or Key. A name that does resolve is rejected with E01091.
WHY
'twice() of type Integer' with '-> amount as Integer' would otherwise compile - and 'twice() of String' then takes and returns a String, while every declaration in the function body reads 'Integer'. The compiler knows 'Integer' there means the parameter; a reader, or an AI, reads the built-in Integer and draws the wrong conclusions about overflow, arithmetic and what the function accepts.
HOW IT IS CHECKED
The name is resolved from the MODULE scope once every construct of the program is known, so a class declared further down the file is still found. A name brought in with 'references' is rejected even earlier, as E03010.
This program shows the correct form: 'twice() of type T' reads as a placeholder, and the same function then works for Integer (21 + 21 = 42) and for String ("ha" + "ha" = "haha").
Example
defines module qa.naming.typeparameters defines function twice() of type T -> amount as T <- rtn as T: amount + amount //Declared AFTER twice() - a type parameter still may not take its name (E01091). defines class Widget label <- String() default operator ? defines program TypeParameterNamesDemo() stdout <- Stdout() numbers <- twice() of Integer stdout.println($numbers(21)) words <- twice() of String stdout.println(words("ha"))
Common mistakes
E01091 — Integer resolves to the built-in type, so as a type parameter name it gives 'Integer' a second meaning inside the function. Use a placeholder such as T. See ek9 -h E01091.
Incorrect:
twice() of type Integer -> amount as Integer <- rtn as Integer: amount + amount
Correct:
twice() of type T -> amount as T <- rtn as T: amount + amount
E01091 — Widget is a class in this module, even if declared later in the file - a type parameter may not reuse its name. See ek9 -h E01091.
Incorrect:
twice() of type Widget -> amount as Widget <- rtn as Widget: amount + amount
Correct:
twice() of type T -> amount as T <- rtn as T: amount + amount
Other ways to ask this
- What is E01091 in EK9?
- Why can't a generic function be declared 'of type Integer'?
- Why does EK9 reject a type parameter that names an existing type?
- What does 'a type parameter name must not resolve to anything' mean?
Coming from another language?
Java: 'class Box<String>' is legal and declares a type variable named String that shadows java.lang.String inside the class - a known puzzler. C#, Kotlin and TypeScript allow the same. EK9 rejects a type parameter name that resolves to anything.
Keywords: generic, type parameter, conceptual type, of type, T, shadow, naming, E01091, placeholder