Why does the compiler require two constructors for my generic class?

← Generics · Ref: Q1071

EK9 generic types require exactly two constructors: a default (no-arg) constructor and a parameterised constructor.

Why two constructors?
1. The DEFAULT constructor creates an unset instance (needed for type inference)
2. The PARAMETERISED constructor creates a set instance with values

BEFORE (E06040 error — only one constructor):

  defines class
    Pair of type (A, B)
      first as A: A()
      second as B: B()
      Pair()
        -> first as A, second as B
        this.first :=: first
        this.second :=: second

AFTER (fixed — both constructors):

  defines class
    Pair of type (A, B)
      first as A: A()
      second as B: B()
      default Pair()
      Pair()
        -> first as A, second as B
        this.first :=: first
        this.second :=: second

The default constructor must be public for generic types (E06060 prevents private). The compiler uses it internally for type inference.

See Q194 for generic class basics. See Q196 for multi-parameter generics. See Q116 for default operator.

Example

defines module qa.generics.twoconstructors

  defines class

    Pair of type (A, B)
      first as A: A()
      second as B: B()

      //Constructor 1: default (used by compiler for type inference)
      default Pair()

      //Constructor 2: parameterised (public — used by code)
      Pair()
        ->
          first as A
          second as B
        this.first :=: first
        this.second :=: second

      override operator ? as pure
        <- rtn as Boolean: first? and second?

      operator $ as pure
        <- rtn as String: `(${$first}, ${$second})`

  defines program

    GenericConstructorDemo()
      stdout <- Stdout()

      pair <- Pair("Alice", 30)
      stdout.println(`Pair: ${pair}`)

Common mistakes

E06040 — Generic types require 2 constructors: a default (no-arg) and a parameterised one. Add 'default private Pair()' for the default constructor.

Incorrect:

    Pair of type (A, B)
      first as A: A()
      second as B: B()

      Pair()
        -> first as A, second as B

Correct:

    Pair of type (A, B)
      first as A: A()
      second as B: B()

      //Constructor 1: default (used by compiler for type inference)
      default Pair()

      //Constructor 2: parameterised (public — used by code)
Other ways to ask this
  • What is E06040 and how do I fix it?
  • My generic class gets 'requires 2 constructors' error
  • How do I define constructors for a generic type in EK9?

Coming from another language?

Java: generics have no constructor requirements. Rust: no constructors, uses associated functions. EK9: generic types MUST have exactly 2 constructors — default (private) and parameterised.

Keywords: private, generic, default, two, E06040, type, constructor