Why must the $$ operator always return JSON in EK9?

← Operators and Expressions · Ref: Q887

The $$ operator is the JSON serialisation operator. It MUST return JSON — returning any other type (String, Integer, etc.) triggers E07580.

OPERATOR CONTRACT

Each accessor operator has a strict return type:

  $ — MUST return String (toString equivalent)
  $$ — MUST return JSON (serialisation)
  #? — MUST return Integer (hashcode)
  ? — MUST return Boolean (isSet)

CORRECT PATTERN

  operator $$ as pure
    <- rtn as JSON: JSON()

INCORRECT PATTERN

  operator $$ as pure
    <- rtn as String: ...   // ERROR: E07580

WHY ENFORCED

JSON serialisation must produce a JSON value, not a String representation. The `$` operator already handles String conversion. Having `$$` return String would be redundant and semantically wrong.

See Q238 for operator overview. See Q242 for conversion operators.

Example

defines module qa.operators.jsonreturn

  defines class

    <?-
      Configuration class with JSON serialisation.
    -?>
    AppConfig
      appName <- "MyApp"
      appVersion <- "1.0.0"

      getName()
        <- rtn as String: String(appName)

      getVersion()
        <- rtn as String: String(appVersion)

      operator $ as pure
        <- rtn as String: `${appName} v${appVersion}`

      operator $$ as pure
        <- rtn as JSON: JSON()

      override operator ? as pure
        <- rtn as Boolean: appName?

  defines program

    JsonOperatorReturnDemo()
      stdout <- Stdout()

      config <- AppConfig()
      stdout.println(`Config: ${config}`)

Common mistakes

E07580 — The $$ operator must return JSON, not String. Use `<- rtn as JSON: JSON()` and populate the JSON object. The $ operator handles String conversion. See ek9 -h E07580 for details.

Incorrect:

      <- rtn as String: "{}"

Correct:

      <- rtn as JSON: JSON()
Other ways to ask this
  • What triggers E07580 MUST_RETURN_JSON?
  • Why does the $$ operator require a JSON return type?
  • How do I implement the JSON serialisation operator?

Coming from another language?

Java: no operator overloading, toString() returns String. Python: __repr__ and __str__ both return str, no JSON operator. Rust: Serialize trait via serde. Go: json.Marshaler returns []byte. EK9: separate $ (String) and $$ (JSON) operators with enforced return types.

Keywords: E07580, class, enforce, JSON, serialisation, accessor, return, operator, contract, type