Walk me through fixing error E05030 'not open to be extended' for three different cases: extending a closed class, extending a closed function, and extending a built-in type.
← Debugging and Troubleshooting · Ref: Q1254
E05030 'not open to be extended' is raised whenever you try to extend a type that is closed. There are THREE distinct scenarios and each has a different fix.
CASE 1: EXTENDING A CLOSED USER CLASS
Problem: You own the parent class but forgot 'as open':
AuditLogger // CLOSED by default default AuditLogger()
FileAuditLogger extends AuditLogger // E05030 default FileAuditLogger()
Fix: add 'as open' to the parent:
AuditLogger as open // Now extensible default AuditLogger()
CASE 2: EXTENDING A CLOSED USER FUNCTION
Problem: You try to extend a concrete function that is closed:
formatter() // CLOSED by default -> input as String <- rtn as String: input.trim()
upper <- () is formatter as function // E05030 — formatter is closed rtn: input.trim().upperCase()
Fix: add 'as open' to the parent function:
formatter() as open // Now extensible -> input as String <- rtn as String: input.trim()
CASE 3: EXTENDING A BUILT-IN CLOSED TYPE
Problem: Many built-in types are closed and can never be extended - the generics List, Dict, Optional, Result, PriorityQueue and others. (A few built-ins, such as String and Integer, ARE declared 'as open'; 'ek9 -h <Type>' shows which.)
StringList extends List of String // E05030 - List is closed default StringList()
Fix: use COMPOSITION instead — hold the built-in as a field:
StringCollection
items as List of String: List() of String
default StringCollection()
add()
-> item as String
items += item
size() as pure <- rtn as Integer: length items
default operator ?
CHOOSING THE RIGHT FIX
- Case 1 and Case 2 are fine to fix with 'as open' IF you own the parent AND inheritance is the right design.
- For Case 3 (a closed built-in type) you MUST use composition. Those built-ins are deliberately closed to prevent subclasses from breaking invariants.
- Whenever possible, prefer composition over inheritance even for your own classes.
See Q1043 for the E05030 diagnosis flow. See Q1250 for 'as open' on classes. See Q1252 for 'as open' on functions.
Example
defines module qa.debugging.fixe05030cases defines class AuditLogger as open default AuditLogger() log() -> message as String stdout <- Stdout() stdout.println("[AUDIT] " + message) default operator ? FileAuditLogger extends AuditLogger default FileAuditLogger() override log() -> message as String stdout <- Stdout() stdout.println("[FILE-AUDIT] " + message) default operator ? StringCollection items as List of String: List() of String default StringCollection() add() -> item as String items += item size() as pure <- rtn as Integer: length items default operator ? defines function formatter() as open -> input as String <- rtn as String: input.trim() defines program FixE05030Demo() stdout <- Stdout() logger <- FileAuditLogger() logger.log("case 1: class extension via 'as open'") upper <- () is formatter as function rtn: input.trim().upperCase() stdout.println(`case 2: open function extended dynamically -> ${upper(" ek9 ")}`) collection <- StringCollection() collection.add("case 3: composition") collection.add("holds a List") stdout.println(`case 3: collection size -> ${collection.size()}`)
Common mistakes
E05030 — List is closed (not open to be extended); use composition and hold the List as a property. See ek9 -h E05030 for details.
Incorrect:
StringCollection extends List of String items as List of String: List() of String
Correct:
StringCollection
items as List of String: List() of String
Other ways to ask this
- How do I fix E05030 in EK9?
- Give me three worked examples of fixing E05030.
- The compiler says 'not open to be extended' — show me the fixes.
- Walk me through the three common causes of E05030 and how to resolve each.
Coming from another language?
Java: final keyword closes classes, subclasses can bypass accidentally. Kotlin: closed by default like EK9, use 'open' keyword. Scala: final keyword closes. C#: sealed keyword closes. EK9: E05030 catches all three cases at compile time — no runtime surprise.
Keywords: three cases, E05030, built-in, fix, extends, composition, open, closed