Create me a Customer record and use the DOUBLE-dollar $$ operator to convert it to a JSON representation — not plain text.

← Operators and Expressions · Ref: Q1256

The DOUBLE-dollar operator $$ produces a JSON representation of a value. It is distinct from the single-dollar $ operator (which produces plain text). Override 'operator $$' on a user-defined record to control what $$ returns — typically constructing a JSON object from the record's fields.

CUSTOMER RECORD WITH $$ OVERRIDE

  Customer
    id as Integer: 0
    firstName as String: String()
    lastName as String: String()
    Customer()
      ->
        id as Integer
        firstName as String
        lastName as String
      this.id :=: id
      this.firstName :=: firstName
      this.lastName :=: lastName
    override operator $$ as pure
      <- rtn as JSON: JSON()
        rtn.object()
        rtn += JSON("id", $id)
        rtn += JSON("firstName", firstName)
        rtn += JSON("lastName", lastName)
    default operator ?

USAGE

  customer <- Customer(1001, "Ada", "Lovelace")
  jsonValue <- $$customer
  stdout.println($jsonValue)
  // Output: {"id":1001,"firstName":"Ada","lastName":"Lovelace"}

WHAT $$ DOES

- Returns a JSON value (type JSON, not String)
- Used to serialise records to wire format
- Is the OPPOSITE of $ — $$ is JSON, $ is plain text (see Q1255)

This file uses ONLY the $$ operator so the distinction from $ is absolutely clear. Every use of a dollar sign operator here is double-dollar.

NOTE ON THE DIFFERENCE

- $ returns String (plain text, for humans)
- $$ returns JSON (structured, for machines)
The two are DIFFERENT operators with DIFFERENT return types. Do not confuse them.

See Q1255 for the $ string operator contrast. See Q887 for the JSON operator return type. See Q1094 for $ and $$ in context.

Example

defines module qa.operators.dollardollarjsoncustomer

  defines class

    Customer
      id as Integer: 0
      firstName as String: String()
      lastName as String: String()

      Customer()
        ->
          id as Integer
          firstName as String
          lastName as String
        this.id :=: id
        this.firstName :=: firstName
        this.lastName :=: lastName

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

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

  defines program

    DollarDollarJsonCustomerDemo()
      stdout <- Stdout()

      customer <- Customer(1001, "Ada", "Lovelace")
      jsonValue <- $$customer
      stdout.println(`JSON: ${jsonValue}`)

Common mistakes

E07570 — Operator $ must return a String; to return JSON use the double-dollar $$ operator instead of $. See ek9 -h E07570 for details.

Incorrect:

operator $ as pure

Correct:

operator $$ as pure
Other ways to ask this
  • Show me how to use the $$ operator on a custom record for JSON output.
  • Write a Customer record with a $$ operator that returns a JSON value.
  • Give me a record example that uses just the $$ operator, not $.
  • How do I override operator $$ to produce a JSON representation of a record?

Coming from another language?

Java: custom toJson() methods or Jackson/Gson annotations. Kotlin: kotlinx.serialization @Serializable. Python: __json__ convention or dataclass asdict. Rust: serde Serialize. EK9: 'operator $$' is built-in syntax for JSON conversion, returning a JSON value directly.

Keywords: JSON conversion, $$, JSON operator, serialization, double dollar, Customer