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