Skip to content

CEP-0055: Compound Assignment Operators

Draft

Draft proposal for post-V1 compound assignment operators. V1 rejects +=, -=, *=, /=, and %= and requires explicit assignment.

Summary

Catalyst should eventually add compound assignment operators for the arithmetic operator families:

a += b
a -= b
a *= b
a /= b
a %= b

V1 keeps these spellings deferred because assignment, place evaluation, moves, resource overwrite checks, and mutating operator contracts need a precise shared model.

Proposed Direction

Compound assignment should have a default lowering through the corresponding binary operator when no more specific mutating operation is selected:

a += b

is semantically equivalent to:

a = a + b

The final design must define this equivalence in terms of places, not repeated source evaluation. A complex left-hand side such as items[index()] += value should evaluate the destination place and side effects according to one explicit rule, then perform the read, arithmetic operation, and store.

The default lowering is available only when the binary operator result is assignable to the destination place type.

Compound assignment should also allow an optional mutating override through explicit operation contracts such as:

fn AddAssign(comptime Rhs: Type) Type {
  return contract {
    fn add_assign(self: *Self, rhs: *const Rhs) void
  }
}

Corresponding families would be needed for subtraction, multiplication, division, and remainder. A mutating override lets large, resource-owning, or allocation-sensitive types update in place without forcing a temporary result.

Design Questions

  • whether mutating override contracts live in the prelude beside arithmetic operation contracts;
  • whether a += b prefers a visible mutating override over default binary-operator lowering;
  • how ambiguity is diagnosed when multiple mutating implementations are visible;
  • how the lowering interacts with indexing places, field places, pointer dereference places, and resource overwrite linting;
  • whether the right-hand operand is passed by pointer, value, or move for each mutating contract family;
  • whether mutating overrides may fail, allocate, or require capabilities, and whether those requirements belong in separate named APIs instead of compound assignment.

V1 Compatibility

V1 source rejects compound assignment operators. Programmers must write the operation explicitly:

x = x + 1

This keeps the current assignment model simple while preserving a compatible path to future sugar and optional in-place overrides.