How do I extend or specialize a generic type in EK9?
← Generics · Ref: Q197
EK9 allows extending generic types that are marked 'as open'. You create concrete specializations by providing specific type arguments.
OPEN GENERIC TYPES
Mark a generic type as open to allow extension:
BaseList of type T as open items as List of T?
SPECIALIZATION VIA EXTENSION
Create a concrete type by extending with specific types:
NameList is BaseList of String
NameList is now a concrete class with String-typed items.
ADDING METHODS
Specializations can add new methods:
NameList is BaseList of String findByPrefix() -> prefix as String <- rtn as String?
GENERIC FUNCTION INSTANTIATION
Generic functions use 'is' or 'extends' for instantiation:
intCompare <- () is compareFunc of Integer as function
See Q194 for generic classes. See Q101 for closed by default. See Q102 for as open. See Q58 for generic functions.
Example
#!ek9 defines module qa.generics.extending defines function compareFunc() of type T as open -> item1 as T item2 as T <- rtn as Integer := item1 <=> item2 defines class BaseList of type T as open items as List of T? BaseList() items :=? List() of T BaseList() -> item as T items: List() of T items += item addItem() -> item as T if not items? items: List() of T items += item count() as pure <- rtn as Integer: 0 if items? rtn: length items default operator ? // Specialization: concrete type from generic NameList is BaseList of String default operator ? defines program ExtendingGenericsDemo() stdout <- Stdout() // === GENERIC FUNCTION INSTANTIATION === intCompare <- () is compareFunc of Integer as function result <- intCompare(10, 20) stdout.println(`Compare 10 vs 20: ${result}`) strCompare <- () extends compareFunc of String as function strResult <- strCompare("apple", "banana") stdout.println(`Compare apple vs banana: ${strResult}`) // === SPECIALIZED CLASS === names <- NameList() names.addItem("Alice") names.addItem("Bob") stdout.println(`Name count: ${names.count()}`)
Common mistakes
E50020 — Generic functions must be instantiated with 'as function', not 'as class'. Using the wrong construct type triggers E50020 - incompatible genus (the generic is a function, not a class). See ek9 -h E50020 for details.
Incorrect:
intCompare <- () is compareFunc of Integer as class
Correct:
intCompare <- () is compareFunc of Integer as function
Other ways to ask this
- How do I create a concrete type from a generic in EK9?
- Can I extend a parameterized type in EK9?
- How does generic specialization work in EK9?
Coming from another language?
Java: class NameList extends ArrayList<String>. C++: template specialization or typedef. Rust: type alias or newtype pattern. Go: type NameList = List[string] (no true specialization). Kotlin: class NameList : ArrayList<String>(). EK9: 'NameList is BaseList of String' with optional additional methods.
Keywords: concrete, extend, generic, inherit, open, parameterize, parameterized, specialize, type, type-parameter