E06010: type/function is generic but no parameters were supplied
What went wrong
A generic type or function requires type parameters but none were provided. You must specify what types the generic operates on using the 'of' clause.
Worked examples
Compilable examples demonstrating this error and the correct fix:
- ek9 -q 681 (What is the correct syntax for generic type parameterizat...)
- ek9 -q 742 (How does EK9 detect when a function type or generic type ...)
- ek9 -q 45 (How does the List type work in EK9?)
- ek9 -q 46 (How does the Dict type work in EK9?)
- ek9 -q 127 (How does collection type inference work in EK9?)
[TARGET-TYPED CONSTRUCTION] A bare 'G()' is completed from its DECLARED type when that type is a parameterisation of exactly that generic - a typed declaration, a ':', ':=', '=' or ':=?' assignment to a declared variable, a returning variable, a property, or a field reached through an object:
- //A typed declaration, and an assignment to a declared variable
- names as List of String: List()
- names := List()
- //A field through 'this', and a field through another object
- this.lines := List()
- other <- Order()
- other.lines: List()
- //A generic function's value
- fn as echo of Integer: echo()
'<-' declares no type, so 'names <- List()' is this error; a target of another generic ('x as Optional of String: List()'), a non-generic target, or 'List().reverse()' completes nothing. A ternary arm and an argument are not targets either (an argument takes part in choosing the overload) - write the type arguments there:
- //A ternary arm and an argument are not targets: write the type arguments there
- this.lines := accepted <- List() of String else ["none"]
- count <- countOf(List() of String)
Type inference alternative
When creating with literal values, types can be inferred: '["a", "b", "c"]' is a List of String and '{"key": 123}' a Dict of (String, Integer).
How to fix it
- Add 'of TypeName' after the generic type constructor: 'names <- List() of String'
- For multiple parameters: use 'of (Type1, Type2)'
- Or declare the target's type and construct bare: 'names as List of String: List()'
- Or use literal syntax if initializing with values
Common generic types and parameters
- List of T - element type
- Dict of (K, V) - key type, value type
- Optional of T - contained type
- Result of (T, E) - success type, error type
- Function of (T, R) - input type, return type
Common causes
- Forgetting to specify type parameter
- Coming from dynamically-typed languages
- Assuming type can always be inferred (it can't without values)
See also
Examples
Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.
Fails with E06010: type/function is generic but no parameters were supplied
#!ek9 defines module error.e06010.bad defines function <?- Valid uses of built-in generics for comparison. -?> ValidBuiltInGenericUse() stdout <- Stdout() validOpt <- Optional("Hello") stdout.println(`opt: ${validOpt}`) validOpt2 <- Optional() of String stdout.println(`opt2 set: ${validOpt2?}`) validList <- [1, 2, 3] stdout.println(`list: ${validList}`) <?- Bare Optional() without type parameters. -?> BareOptionalCall() bareOpt <- Optional() Stdout().println(`${bareOpt?}`) <?- Bare List() without type parameters. -?> BareListCall() bareList <- List() Stdout().println(`${bareList}`) <?- Bare Result() without type parameters. -?> BareResultCall() bareResult <- Result() Stdout().println(`${bareResult?}`)
Fixed: Say what it holds: of String, of Integer, of (Integer, String)
#!ek9 defines module error.e06010.good.fix defines function <?- Valid uses of built-in generics for comparison. -?> ValidBuiltInGenericUse() stdout <- Stdout() validOpt <- Optional("Hello") stdout.println(`opt: ${validOpt}`) validOpt2 <- Optional() of String stdout.println(`opt2 set: ${validOpt2?}`) validList <- [1, 2, 3] stdout.println(`list: ${validList}`) <?- Bare Optional() without type parameters. -?> BareOptionalCall() bareOpt <- Optional() of String Stdout().println(`${bareOpt?}`) <?- Bare List() without type parameters. -?> BareListCall() bareList <- List() of Integer Stdout().println(`${bareList}`) <?- Bare Result() without type parameters. -?> BareResultCall() bareResult <- Result() of (Integer, String) Stdout().println(`${bareResult?}`)
Fixed: Say what the generic holds: Optional() of String - or declare the type and let it be the target
#!ek9 defines module error.e06010.good defines function typedCalls() stdout <- Stdout() nothingYet <- Optional() of String names as List of String: List() outcome as Result of (String, Integer): Result() stdout.println(`${nothingYet?} ${length names} ${outcome?}`)
Fixed: A bare G() takes its type arguments from a declared target of the same generic
#!ek9 defines module error.e06010.good.targets defines function echo() of type T -> item as T <- rtn as T: item defines class Order lines as List of String: List() replaceLines() //A typed declaration, and an assignment to a declared variable names as List of String: List() names := List() //A field through 'this', and a field through another object this.lines := List() other <- Order() other.lines: List() //A generic function's value fn as echo of Integer: echo() lines += names lines += other.lines require fn? replaceWhenAccepted() -> accepted as Boolean //A ternary arm and an argument are not targets: write the type arguments there this.lines := accepted <- List() of String else ["none"] count <- countOf(List() of String) require count? countOf() -> items as List of String <- rtn as Integer: length items default operator ?
Questions and answers
These Q&A entries show E06010 and its fix:
- Q45: How does the List type work in EK9?
- Q46: How does the Dict type work in EK9?
- Q127: How does collection type inference work in EK9?
- Q681: What is the correct syntax for generic type parameterization and instantiation?
- Q742: How does EK9 detect when a function type or generic type is used incorrectly?
- Q744: How does EK9 reject constructing a program or application, and abstract types in sealed allow only lists?
- Q948: Why must generic types always be parameterized when used?