Why can't a local construct share a name with a referenced (imported) type in EK9?

← Syntax and Structure Rules · Ref: Q1306

EK9 refuses to pick a winner when a locally-defined construct (class, record, trait, function) shares its name with a type brought in via a 'references' block. Both the import and the local definition want the same short name, so any later use of that name is ambiguous - the compiler rejects it immediately with E03010 rather than silently choosing one.

Fix: rename the local construct to a distinct name (e.g. ItemList instead of List). The referenced type keeps its short name, the local type gets its own, and every use resolves to exactly one symbol. Alternatively, drop the reference and use the fully qualified 'module::Type' form inline when the imported type is needed.

See Q726 for references block syntax. See Q832 for the design rationale.

Example

defines module qa.syntaxrules.referencecollision

  //'List' is imported via references and keeps that short name.
  references
    org.ek9.lang::List

  //THE FIX: the local construct is named distinctly (ItemList), so it does
  //NOT collide with the referenced 'List'. Naming this class 'List' would
  //trigger E03010 CONSTRUCT_REFERENCE_CONFLICT.
  defines class

    ItemList
      items as List of String?

      ItemList()
        items: List() of String

      ItemList()
        -> initial as String
        items: List() of String
        items += initial

      add()
        -> item as String
        items += item

      size()
        <- rtn as Integer: length items

      default operator ?

  defines program

    ReferenceCollisionDemo()
      stdout <- Stdout()

      //'List' resolves unambiguously to the referenced org.ek9.lang::List.
      basket <- ItemList("apple")
      basket.add("pear")

      stdout.println(`Basket holds ${basket.size()} items`)

Common mistakes

E03010 — Importing 'List' via references and then defining a local class also named 'List' makes the short name 'List' ambiguous - neither the import nor the local definition takes priority, so EK9 raises E03010. Rename the local construct (ItemList) so each name resolves to exactly one symbol, or drop the reference and use the fully qualified org.ek9.lang::List inline. See ek9 -h E03010 for details.

Incorrect:

references
  org.ek9.lang::List
defines class
  List

Correct:

  references
    org.ek9.lang::List

  //THE FIX: the local construct is named distinctly (ItemList), so it does
Other ways to ask this
  • What triggers E03010 CONSTRUCT_REFERENCE_CONFLICT?
  • Why does importing List then defining a local class List fail to compile?
  • How do I resolve a name collision between a references import and a local type?

Coming from another language?

Java: wildcard imports (import java.util.*) silently shadow local types; the conflict surfaces only when two imports expose the same name. Python: 'from module import *' overwrites local names with no warning. C#: 'using' directives let a local type silently win over an imported one. EK9: neither the reference nor the local takes priority - the collision is a compile-time error (E03010) and the developer must choose a distinct name.

Keywords: references, rename, collision, name, E03010, syntax, local, conflict, import