How do copy, replace, and merge operators work with constrained types?
← Advanced Type System · Ref: Q719
Constrained types inherit copy (:=:), replace (:^:), and merge (:~:) operators from their base type, with both operands being the constrained type.
COPY (:=:) DELEGATES TO BASE TYPE
Copy duplicates the value from one variable to another:
target <- DrivingAge(50) source <- DrivingAge(60) target :=: source //target is now 60
Both operands must be the same constrained type.
REPLACE (:^:) OVERWRITES
Replace destructively overwrites the target value:
target :^: DrivingAge(70) //target is now 70
The semantics depend on the base type's replace implementation.
MERGE (:~:) FILLS, NEVER OVERWRITES
Merge follows the one rule every type shares: ':~:' never overwrites a set value; it fills whatever is unset or missing. A constrained value is a single value, so it takes the source only when it is unset:
target :~: DrivingAge(80) //target is set (70), so it stays 70 empty <- DrivingAge() empty :~: DrivingAge(80) //empty was unset, so it is now 80
To overwrite a set value use :=: or :^:.
ARGUMENT TYPE IS CONSTRAINED TYPE
These operators take the constrained type as argument, not the raw base type:
target :=: DrivingAge(50) //correct //target :=: 50 //wrong — cannot use raw Integer
See Q257 for constrained type overview. See Q241 for mutation operator details. See Q716 for arithmetic operators.
Example
#!ek9 defines module qa.advancedtypes.constrainedcopyreplacemerge defines type DrivingAge as Integer constrain as >= 16 and <= 100 defines program ConstrainedCopyReplaceMergeDemo() stdout <- Stdout() // === COPY (:=:) === target <- DrivingAge(50) source <- DrivingAge(60) stdout.println(`Before copy: target=${target}, source=${source}`) target :=: source stdout.println(`After copy: target=${target}`) // === REPLACE (:^:) === target :^: DrivingAge(70) stdout.println(`After replace with 70: target=${target}`) // === MERGE (:~:) === //Merge never overwrites a set value - mergeTarget keeps 20 mergeTarget <- DrivingAge(20) mergeSource <- DrivingAge(30) mergeTarget :~: mergeSource stdout.println(`After merge of 30 into 20: mergeTarget=${mergeTarget}`) //An unset target is filled by a set source emptyTarget <- DrivingAge() emptyTarget :~: mergeSource stdout.println(`After merge into unset: emptyTarget=${emptyTarget}`) // === COPY CONSTRUCTOR (separate from :=:) === original <- DrivingAge(25) copied <- DrivingAge(original) stdout.println(`Original: ${original}, Copied: ${copied}`) // === ASSIGNMENT (:=) VS COPY (:=:) === a <- DrivingAge(40) b <- DrivingAge(60) //Assignment replaces the variable reference a := b stdout.println(`After assignment a := b: a=${a}`) //Copy delegates to base type copy operator c <- DrivingAge(40) d <- DrivingAge(60) c :=: d stdout.println(`After copy c :=: d: c=${c}`)
Common mistakes
E50060 — DrivingAge has no intValue() method in EK9. DrivingAge is a constrained type, not a wrapper. See ek9 -h E50060 for details.
Incorrect:
target <- DrivingAge(50).intValue()
Correct:
target <- DrivingAge(50)
E50060 — DrivingAge has no intValue() method in EK9. Use the promote operator (#^) to extract the Integer value. See ek9 -h E50060 for details.
Incorrect:
copied <- DrivingAge(original).intValue()
Correct:
copied <- DrivingAge(original)
Other ways to ask this
- Can I use :=:, :^:, and :~: with constrained types?
- How do I copy values between constrained type variables?
- What is the difference between copy, replace, and merge for constrained types?
Coming from another language?
Java: no constrained types, no copy/replace/merge operators. Manual clone() or copy constructors. Python: copy.copy() and copy.deepcopy() for object copying. Rust: Clone trait for copy, no replace/merge concept. Go: assignment copies values for value types. Kotlin: data class copy() method. EK9: constrained types inherit :=: (copy), :^: (replace), :~: (merge) from their base type — these operate between same-type constrained values, delegating to the base type's implementation.
Keywords: assignment, constrained, copy, delegate, merge, mutating, operator, replace, transfer