What is the difference between :=: :^: and :~: in EK9?

← Operators and Expressions · Ref: Q1058

EK9 has three operators for transferring content between objects:

:=: COPY — copies all fields from source to target:

  target :=: source

Every field in source is copied to target, overwriting all existing values. The default implementation does a shallow copy (field references are shared).

:~: MERGE — copies only SET fields from source to target:

  target :~: source

Only fields that are SET in source are copied. Unset fields in source leave the target fields unchanged. Use this for partial updates.

:^: REPLACE — replaces the entire content:

  target :^: source

Fully replaces the target content with the source. Similar to :=: but semantically means 'this object is now that object'.

All three are mutation operators — they modify the target in place and return nothing. They cannot be marked 'as pure'.

Custom :~: example (merge only SET fields):

  operator :~:
    -> from as Config
    if from.host?
      host :=: from.host
    if from.port?
      port :=: from.port

See Q98 for record operators. See Q241 for all mutation operators. See Q116 for default operator generation.

Example

defines module qa.operators.copyreplacemerge

  defines record

    Config
      host as String: String()
      port as Integer: 0

      Config()
        ->
          host as String
          port as Integer
        this.host :=: host
        this.port :=: port

      //:~: MERGE — only copies SET fields
      operator :~:
        -> from as Config
        if from.host?
          host :=: from.host
        if from.port?
          port :=: from.port

      default operator

  defines program

    CopyReplaceMergeDemo()
      stdout <- Stdout()

      original <- Config("localhost", 8080)
      stdout.println(`Original: ${original}`)

      // :=: COPY — all fields copied
      backup <- Config("", 0)
      backup :=: original
      stdout.println(`Copy: ${backup}`)

      // :~: MERGE — only set fields from partial are copied
      partial <- Config("remote.host", 9090)
      original :~: partial
      stdout.println(`After merge: ${original}`)

Common mistakes

E50060 — EK9 has no '.clone()' method; use ':=:' to copy all fields (':~:' merge, ':^:' replace). See ek9 -h E50060 for details.

Incorrect:

      backup := original.clone()

Correct:

      backup :=: original
Other ways to ask this
  • How do copy, replace, and merge operators work?
  • When should I use :=: vs :~: vs :^:?
  • Explain the three content transfer operators

Coming from another language?

Java: clone() or copy constructor. Python: copy.copy() / copy.deepcopy(). Rust: Clone trait. EK9 has three distinct operators: :=: (copy all), :~: (merge set only), :^: (replace).

Keywords: mutation, transfer, operator, replace, merge, copy