E01091: a type parameter name must not resolve to anything; use a conceptual name such as 'T'
What went wrong
A generic type or function declares a type parameter whose name resolves to something that already exists - a built-in type, one of your own classes or functions (even one declared later in the file), or a constant. A type parameter is a placeholder, so its name must not resolve to anything at all.
'twice() of type Integer' with '-> amount as Integer' would otherwise compile, and 'twice() of String' would then take and return a String while every declaration inside the function still reads 'Integer'. The compiler knows 'Integer' there means the parameter; a reader - person or AI - reads the built-in Integer and draws the wrong conclusions.
The name is resolved from the module scope once every construct in the program is known, so a class declared further down the file is found too. (A name brought in with 'references' is rejected earlier, as E03010.)
Worked examples
Compilable examples demonstrating this error and the correct fix:
- ek9 -q 1390 (What can I name the type parameters of a generic type or function?)
Common causes
- Naming the type parameter after the type you first had in mind (of type Integer)
- Reusing the name of one of your own classes as the parameter (of type Widget)
- Carrying over a Java/C#/Kotlin habit, where 'class Box<String>' is legal
How to fix it
Use a conceptual placeholder: T, K, V, or a descriptive one that names nothing real, such as Element or Key.
The [EXAMPLE] section below shows each kind of resolving name (a built-in, a later class, a function, a constant) and the same generics with conceptual names.
See also
Examples
Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.
Fails with E01091: a type parameter name must not resolve to anything; use a conceptual name such as 'T'
#!ek9 defines module error.e01091.bad defines constant LIMIT <- 10 defines class //A built-in type, on a generic class Holder of type String default Holder() as pure Holder() as pure -> seed as String require seed? default operator ? //Only the SECOND type parameter resolves Pairing of type (K, Widget) default Pairing() as pure Pairing() as pure -> first as K second as Widget require first? and second? default operator ? Widget label as String: "widget" default operator ? defines function //A built-in type twice() of type Integer -> item as Integer <- rtn as Integer: item + item //This module's own class - declared LATER in the file wrapLater() of type Widget -> item as Widget <- rtn as Widget: item //A function of this module passOn() of type helper -> item as helper <- rtn as helper: item //A constant of this module limited() of type LIMIT -> item as LIMIT <- rtn as LIMIT: item helper() <- rtn as String: "helper" //Conceptual names are fine - they resolve to nothing fine() of type Element -> item as Element <- rtn as Element: item
Fixed: Use conceptual type parameter names that resolve to nothing: T, K, V, Element
#!ek9 defines module error.e01091.good defines class Holder of type T default Holder() as pure Holder() as pure -> seed as T require seed? default operator ? Pairing of type (K, V) default Pairing() as pure Pairing() as pure -> first as K second as V require first? and second? default operator ? defines function twice() of type T -> item as T <- rtn as List of T: [item, item]
Questions and answers
These Q&A entries show E01091 and its fix: