How does constructor delegation work with pure constructors?

← Constructor Delegation · Ref: Q586

Pure constructors can use both this() and super() delegation, following the same first-statement rule. The key requirement is that ALL constructors must be consistently pure (E05190).

PURE THIS() DELEGATION

Pure constructors can delegate to another pure constructor with this():

  Config() as pure
    -> host as String
    this(host, 8080)
  Config() as pure
    -> host as String, port as Integer
    this.host :=? host
    this.port :=? port

PURE SUPER() DELEGATION

Pure child constructors can call pure parent constructors with super():

  Child() as pure
    -> name as String, extra as Integer
    super(name)
    this.extra :=? extra

CONSISTENCY REQUIREMENT

If the parent has pure constructors, and you extend it, your constructors must also be pure. If the parent has non-pure constructors, your constructors must also be non-pure.

GUARDED ASSIGNMENT

Pure constructors use ':=?' for field assignment after delegation. The delegated constructor may have already set some fields.

See Q563 for pure constructor basics. See Q564 for all-or-nothing purity. See Q565 for multiple pure constructors. See Q580 for this() delegation.

Example

defines module qa.constructor.puredelegation

  defines class

    //Parent with pure constructors
    Coordinates as open
      latitude as Float: Float()
      longitude as Float: Float()

      Coordinates() as pure
        ->
          latitude as Float
          longitude as Float
        this.latitude :=? latitude
        this.longitude :=? longitude

      latitude() as pure
        <- rtn as Float: latitude

      longitude() as pure
        <- rtn as Float: longitude

      default operator ?

    //Child: pure constructors with both this() and super()
    Location extends Coordinates
      locationName <- String()

      //this() delegation in pure constructor
      Location() as pure
        -> locationName as String
        this(locationName, 0.0, 0.0)

      //super() delegation in pure constructor
      Location() as pure
        ->
          locationName as String
          latitude as Float
          longitude as Float
        super(latitude, longitude)
        this.locationName :=? locationName

      locationName() as pure
        <- rtn as String: locationName

      default operator ?

  defines program

    PureConstructorDelegationDemo()
      stdout <- Stdout()

      //this() delegation path
      loc1 <- Location("Unknown")
      stdout.println(`${loc1.locationName()}: (${loc1.latitude()}, ${loc1.longitude()})`)

      //super() delegation path
      loc2 <- Location("London", 51.5074, -0.1278)
      stdout.println(`${loc2.locationName()}: (${loc2.latitude()}, ${loc2.longitude()})`)

Common mistakes

E05190 — If any constructor is pure, ALL constructors must be pure. Mixing pure and non-pure constructors in the same class is invalid. See ek9 -h E05190 for details.

Incorrect:

Location()
        -> locationName as String
        this(locationName, 0.0, 0.0)

Correct:

Location() as pure
        -> locationName as String
        this(locationName, 0.0, 0.0)

E05050 — Even in pure constructors, super() must be the first statement. No field assignments can precede the parent delegation. See ek9 -h E05050 for details.

Incorrect:

Location() as pure
        ->
          locationName as String
          latitude as Float
          longitude as Float
        this.locationName :=? locationName
        super(latitude, longitude)

Correct:

Location() as pure
        ->
          locationName as String
          latitude as Float
          longitude as Float
        super(latitude, longitude)
        this.locationName :=? locationName
Other ways to ask this
  • Can pure constructors use this() and super()?
  • How do I chain pure constructors with delegation?
  • What are the rules for pure constructor delegation?

Coming from another language?

Java: no pure constructor concept. Kotlin: no constructor purity. EK9: pure constructors support this() and super() delegation, all constructors must be consistently pure (E05190), :=? for field assignment.

Keywords: super, pure, constructor, E05190, side-effect, chain, guarded, null-safe, constant, immutable, delegation, this, safe, isset