Why does EK9 require 'defines class' and 'defines function' section headers?

← Syntax and Structure Rules · Ref: Q893

EK9 uses mandatory section headers to organize code into typed blocks. This works like Pascal's type/var/procedure sections — every construct MUST appear under its appropriate 'defines' header.

Like Pascal's 'type' section where you declare types, EK9's 'defines class' section is where you declare classes. Like Pascal's 'procedure' section, EK9's 'defines function' section is where you declare functions.

MANDATORY SECTION HEADERS

EK9 requires the following section headers:
- defines module — declares the module (package), MUST be first
- defines class — contains class definitions
- defines record — contains record (value type) definitions
- defines function — contains standalone function definitions
- defines trait — contains trait (interface) definitions
- defines program — contains executable entry points
- defines component — contains DI-injectable components
- defines type — contains constrained types and enumerations
- defines constant — contains module-level constants
- defines service — contains HTTP service definitions
- defines application — contains DI wiring

WITHOUT SECTION HEADERS = PARSE FAILURE

Writing a class without 'defines class' above it is a grammar error — the parser rejects it immediately, before any compilation even starts.

WHY THIS DESIGN

- Like Pascal's structured declarations, sections make code self-documenting
- The compiler knows what kind of construct to expect
- AI assistants can generate correct section placement
- Modules can have multiple 'defines class' sections for grouping

MULTIPLE SECTIONS

You can have multiple sections of the same type in one module — useful for grouping related types.

See Q93 for class definitions. See Q49 for function definitions. See Q97 for records vs classes.

Example

defines module qa.syntax.sectionheaders

  defines constant

    DEFAULT_GREETING <- "Hello"

  defines record

    <?-
      Records go under 'defines record' section.
      Like Pascal's record type declaration under 'type'.
    -?>
    Coordinate
      xPos as Float: 0.0
      yPos as Float: 0.0

      Coordinate()
        ->
          xPos as Float
          yPos as Float
        this.xPos :=: xPos
        this.yPos :=: yPos

      default operator

  defines function

    <?-
      Functions go under 'defines function' section.
      Like Pascal's 'procedure'/'function' section.
    -?>
    calculateDistance() as pure
      ->
        pointA as Coordinate
        pointB as Coordinate
      <-
        rtn as Float: 0.0

      diffX <- pointA.xPos - pointB.xPos
      diffY <- pointA.yPos - pointB.yPos
      rtn := sqrt(diffX * diffX + diffY * diffY)

  defines trait

    <?-
      Traits go under 'defines trait' section.
      No braces, no semicolons — just indentation.
    -?>
    Describable
      describe() as pure abstract
        <- rtn as String?

  defines class

    <?-
      Classes go under 'defines class' section.
      Like Pascal's type section for class declarations.
    -?>
    Circle
      origin as Coordinate: Coordinate()
      radius as Float: 1.0

      Circle()
        ->
          origin as Coordinate
          radius as Float
        this.origin :=: origin
        this.radius :=: radius

      area() as pure
        <- rtn as Float: 3.14159 * radius * radius

      default operator

  defines program

    SectionHeadersDemo()
      stdout <- Stdout()

      origin <- Coordinate()
      target <- Coordinate(3.0, 4.0)
      distance <- calculateDistance(origin, target)
      stdout.println(`Distance: ${distance}`)

      circle <- Circle(origin, 5.0)
      stdout.println(`Circle area: ${circle.area()}`)

Common mistakes

E01010 — EK9 requires 'defines class' section header before any class definition. Without it, the parser cannot determine the construct type. Like Pascal requires 'type' before type declarations. See ek9 -h E01000 for details.

Incorrect:

  class Person
    name <- String()

Correct:

  defines class

    <?-
      Classes go under 'defines class' section.

E01010 — EK9 requires 'defines function' section header before function definitions. The 'function' keyword alone is not valid syntax. Like Pascal's 'procedure' section. See ek9 -h E01000 for details.

Incorrect:

  function greet()
    <- rtn as String: "hello"

Correct:

  defines function

    <?-
      Functions go under 'defines function' section.
Other ways to ask this
  • What are EK9 section headers and why are they mandatory?
  • Why can't I just write a class without 'defines class'?
  • What is the 'defines' keyword in EK9?
  • How do EK9 section headers work?

Coming from another language?

Pascal: uses type/var/procedure/function section headers — EK9 follows this pattern with 'defines class/function/record'. Java: no section headers, class/interface at top level. Python: no section headers, class/def anywhere. Go: type/func/var at top level, no grouping required. Kotlin: class/fun at top level. EK9: mandatory 'defines class/function/record/program' section headers organize code — think Pascal's structured declarations.

Keywords: mandatory, defines, Pascal, program, syntax, class, function, record, section, trait, header, module