How do EK9 constructors work with parameters?

← Syntax and Structure Rules · Ref: Q894

EK9 constructor parameters use the '->' data-in port syntax on a SEPARATE LINE after the constructor name — like Go's named return values, the parameters are declared on their own indented block.

BASIC CONSTRUCTOR

The constructor shares the class name. Parameters use '->' on a separate line:

  MyClass()
    -> paramName as Type
    this.field :=: paramName

The '->' means 'data coming IN' (like Go's named return parameters or Ada's 'in' port). The '<-' means 'data going OUT'.

MULTI-PARAMETER CONSTRUCTOR

Multiple parameters each get their own line under '->':

  MyClass()
    ->
      firstName as String
      lastName as String
      birthYear as Integer
    this.firstName :=: firstName
    this.lastName :=: lastName
    this.birthYear :=: birthYear

BODY USES :=: FOR COPY ASSIGNMENT

Inside the constructor body, use ':=:' (copy operator) to copy parameter values into fields. This creates a COPY, ensuring the class owns its data.

SINGLE-LINE vs MULTI-LINE
Single parameter: -> on same line as parameter
Multiple parameters: -> on its own line, then parameters indented below

COMMON MISTAKES

- Putting -> and parameters on the class name line (parse error)
- Using := instead of :=: for field assignment in constructor body
- Forgetting the () after the class name in the constructor

See Q93 for class definitions. See Q95 for field visibility. See Q881 for declaration vs assignment.

Example

defines module qa.syntax.constructors

  defines class

    <?-
      Single-parameter constructor.
      Like Go: func NewPerson(name string) *Person
      EK9: -> on separate line for data-in.
    -?>
    Greeting
      message as String: String()

      Greeting()
        -> message as String
        this.message :=: message

      getMessage() as pure
        <- rtn as String: message

      default operator

    <?-
      Multi-parameter constructor.
      Like Go named return params, each on own line.
      Body uses :=: (copy) to assign fields.
    -?>
    Employee
      employeeName as String: String()
      department as String: String()
      yearJoined as Integer: 0

      Employee()
        ->
          employeeName as String
          department as String
          yearJoined as Integer
        this.employeeName :=: employeeName
        this.department :=: department
        this.yearJoined :=: yearJoined

      describe() as pure
        <- rtn as String: `${employeeName} in ${department} since ${yearJoined}`

      default operator

    <?-
      Constructor with default values via multiple constructors.
      Like Go's functional options pattern.
    -?>
    Configuration
      hostAddress as String: "localhost"
      portNumber as Integer: 8080
      isSecure as Boolean: false

      Configuration()
        ->
          hostAddress as String
          portNumber as Integer
          isSecure as Boolean
        this.hostAddress :=: hostAddress
        this.portNumber :=: portNumber
        this.isSecure :=: isSecure

      Configuration()
        ->
          hostAddress as String
          portNumber as Integer
        this.hostAddress :=: hostAddress
        this.portNumber :=: portNumber

      describe() as pure
        <- rtn as String: `${hostAddress}:${portNumber} secure=${isSecure}`

      default operator

  defines program

    ConstructorDemo()
      stdout <- Stdout()

      hello <- Greeting("Welcome to EK9")
      stdout.println(hello.getMessage())

      engineer <- Employee("Alice", "Engineering", 2023)
      stdout.println(engineer.describe())

      defaultConfig <- Configuration("api.example.com", 443, true)
      stdout.println(defaultConfig.describe())

      simpleConfig <- Configuration("localhost", 3000)
      stdout.println(simpleConfig.describe())

Common mistakes

E01010 — EK9 constructors use -> on a SEPARATE line for parameters, not inline parentheses like Java. The -> means 'data coming in' like Go's named parameters. See ek9 -h E01000 for details.

Incorrect:

    Employee(employeeName as String, department as String)
      this.employeeName :=: employeeName
      this.department :=: department

Correct:

      Employee()
        ->
          employeeName as String
          department as String
          yearJoined as Integer
        this.employeeName :=: employeeName
Other ways to ask this
  • What is the constructor parameter syntax in EK9?
  • How do I pass parameters to an EK9 constructor?
  • Why does my EK9 constructor fail to parse?
  • How do multi-parameter constructors work in EK9?

Coming from another language?

Go: func NewPerson(name string, age int) *Person — named returns on separate lines. Java: public MyClass(String name, int age) { this.name = name; } with braces. Python: def __init__(self, name, age): self.name = name. Kotlin: class MyClass(val name: String, val age: Int) — primary constructor inline. EK9: MyClass() with -> parameters on separate lines, body uses :=: copy operator — think Go's named parameters on separate lines.

Keywords: multi-parameter, class, parameter, arrow, data-in, syntax, constructor, assign, copy, Go