Why cannot I use named dynamic classes inside a generic type definition?
← Generics · Ref: Q648
EK9 does not allow named dynamic classes inside generic type or function definitions. Dynamic classes created inside generics must be anonymous (unnamed).
PROHIBITED PATTERN
Inside a generic body, you cannot define a named dynamic class because the name would need to be monomorphised for each type instantiation, creating ambiguous class identities.
CORRECT PATTERN
Use anonymous dynamic classes with traits:
handler <- () with trait of EventHandler as class override handle() <- rtn as Boolean: true
No name means no monomorphisation conflict.
ALTERNATIVE: DEFINE OUTSIDE
Define the class outside the generic, then use it inside:
ConcreteHandler with trait of EventHandler ...
Then reference ConcreteHandler from within the generic body.
See Q647 for function constraint limits. See Q646 for type inference limits. See Q194 for generic class basics.
Example
defines module qa.genericsdeep.nonameddynamic defines trait <?- Trait used as contract for dynamic classes. -?> Renderable render() as pure abstract <- rtn as String? defines class <?- Named class defined OUTSIDE the generic (correct approach). Can be referenced from inside generic bodies. -?> TextRenderer with trait of Renderable content as String? default private TextRenderer() as pure TextRenderer() as pure -> txt as String content :=? String(txt) override render() as pure <- rtn as String: String(content) override operator ? as pure <- rtn as Boolean: content? <?- Generic class that uses the trait, not named dynamic classes. -?> Displayer of type T constrain by Renderable item as T? default private Displayer() as pure Displayer() as pure -> inputItem as T item :=? inputItem show() <- rtn as String: "empty" if item? rtn: item.render() default operator ? defines program NoDynamicInGenericDemo() stdout <- Stdout() renderer <- TextRenderer("EK9 generics") displayer <- Displayer(renderer) output <- displayer.show() stdout.println(`Display: ${output}`)
Common mistakes
E06090 — Named dynamic classes like 'MyRenderer' are not allowed inside generic type definitions. The generic body is monomorphised for each type parameter, so a named class would be created multiple times. Use anonymous dynamic classes instead. See ek9 -h E06090 for details.
Incorrect:
named as Renderable: MyRenderer() with trait of Renderable as class override render() <- rtn as String: "dynamic"
Correct:
if item? rtn: item.render()
Other ways to ask this
- What is E06090 named dynamic class in generic?
- Can I create dynamic classes inside a generic class body?
- Why are named dynamic classes prohibited in generic definitions?
Coming from another language?
Java: anonymous inner classes freely used inside generics. C++: lambdas and local classes inside templates. Rust: closures inside generic functions. Go: anonymous structs (limited). Kotlin: anonymous objects inside generics. EK9: named dynamic classes prohibited in generic bodies, use anonymous or define outside.
Keywords: named, capture, monomorphisation, anonymous, type-parameter, generic, class, prohibited, E06090, dynamic, closure