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
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 — type not resolved. 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: inherit, extend, parameterized, specialize, open, type-parameter, concrete, generic, parameterize, type