Skip to content

CEP-0021: Type Members

Draft

Draft proposal for associated type members such as Self.Item. V1 uses explicit contract parameters instead of type-member projection.

Summary

Catalyst should eventually decide whether semantic contracts or types can expose associated type members.

V1 keeps applied contracts as ordinary Type values. Relationships such as item type are expressed through explicit contract parameters, for example Sequence(T), not Self.Item.

Example

Possible future shape:

const Iterator = contract {
  type Item

  fn next(self: *Self) ?Self.Item
}

fn first(comptime I: Type satisfies Iterator, iter: *I) ?I.Item {
  return iter.next()
}

The V1 shape keeps the relationship explicit instead:

fn Iterator(comptime Item: Type) => contract {
  fn next(self: *Self) ?Item
}

fn first(comptime Item: Type, comptime I: Type implements Iterator(Item), iter: *I) ?Item {
  return iter.next()
}

Motivation

Type members can reduce repeated type parameters in APIs and make some constraints read naturally. They also introduce a projection model, equality questions, inference questions, and additional reflection surface.

The feature should be accepted only if it solves a concrete API problem better than explicit parameters.

Proposed Direction

The proposal should cover:

  • where type members can be declared;
  • how implementations bind member values;
  • whether members are types only or arbitrary comptime values;
  • how member equality and constraints are checked;
  • how members interact with dyn-safety, reflection, and generic inference;
  • whether member projection is allowed on constraint types, concrete types, or both.

V1 Compatibility

V1 rejects type-member projection as a language feature. Contracts should use explicit parameters such as Iterator(Item) and Sequence(T).