Proposal: Additional Core Traits

Status: Approved Author: Eric (with AI assistance) Created: 2026-01-30 Approved: 2026-01-30 Affects: Compiler, type system, traits


Summary

This proposal formalizes three core traits: Printable, Default, and Traceable.

The Iterable, Iterator, DoubleEndedIterator, and Collect traits are already defined in the Types specification and are not modified by this proposal.


Printable Trait

Definition

trait Printable {
    @to_str (self) -> str
}

Printable provides human-readable string conversion.

Usage

Required for string interpolation without format specs:

let x = 42
`value: {x}`  // Calls x.to_str()

Standard Implementations

TypeOutput
int"42"
float"3.14"
bool"true" or "false"
strIdentity
charSingle character string
byteNumeric string
[T] where T: Printable"[1, 2, 3]"
Option<T> where T: Printable"Some(42)" or "None"
Result<T, E> where both Printable"Ok(42)" or "Err(msg)"

Derivation

#derive(Printable)
type Point = { x: int, y: int }

Point { x: 1, y: 2 }.to_str()  // "Point(1, 2)"

Derived implementation creates human-readable format with type name and field values in order.


Default Trait

Definition

trait Default {
    @default () -> Self
}

Default provides zero/empty values.

Usage

let config: Config = Config.default()
let map: {str: int} = {str: int}.default()  // {}

Standard Implementations

TypeDefault Value
int0
float0.0
boolfalse
str""
byte0
char'\0'
void()
[T][]
{K: V}{}
Set<T>Set.new()
Option<T>None
Duration0ns
Size0b

Derivation

#derive(Default)
type Config = {
    host: str,    // ""
    port: int,    // 0
    debug: bool,  // false
}

All fields must implement Default.

Cannot Derive

Sum types cannot derive Default (ambiguous variant):

#derive(Default)  // ERROR
type Status = Pending | Running | Done

Traceable Trait

Definition

trait Traceable {
    @with_trace (self, entry: TraceEntry) -> Self
    @trace (self) -> str
    @trace_entries (self) -> [TraceEntry]
    @has_trace (self) -> bool
}

Traceable enables error trace propagation.

TraceEntry Type

type TraceEntry = {
    function: str,   // Function name with @ prefix
    file: str,       // Source file path
    line: int,       // Line number
    column: int,     // Column number
}

Usage

Automatic Trace Addition

The ? operator automatically adds trace entries:

@outer () -> Result<int, Error> = {
    let x = inner()?,  // Adds trace entry for this location
    Ok(x * 2)
}

Manual Trace Access

match result {
    Ok(v) -> v
    Err(e) -> {
        for entry in e.trace_entries() do
            log(msg: `  at {entry.function} ({entry.file}:{entry.line})`)
        panic(msg: e.message)
    }
}

Standard Implementations

TypeImplements
ErrorYes
Result<T, E> where E: TraceableYes (delegates to E)

Error Type

type Error = {
    message: str,
    source: Option<Error>,
    // trace stored internally
}

impl Error: Traceable {
    @with_trace (self, entry: TraceEntry) -> Error = ...
    @trace (self) -> str = ...  // Formatted trace string
    @trace_entries (self) -> [TraceEntry] = ...
    @has_trace (self) -> bool = ...
}

Relationships

             Eq
            /  \
     Hashable  Comparable

     Iterator
         |
DoubleEndedIterator

     Printable
         |
    Formattable (blanket impl)

     Traceable (for error types)

Error Messages

Missing Printable

error[E1040]: `MyType` does not implement `Printable`
  --> src/main.ori:5:15
   |
 5 | let s = `value: {my_value}`
   |                  ^^^^^^^^ cannot convert to string
   |
   = help: implement `Printable` or derive it

Cannot Derive Default

error[E1042]: cannot derive `Default` for sum type
  --> src/main.ori:2:1
   |
 2 | type Status = Pending | Running | Done
   | ^^^^^^ sum types have no unambiguous default variant
   |
   = help: implement `Default` manually if needed

Spec Changes Required

Update 07-properties-of-types.md

Add sections for Printable, Default, and Traceable with:

  1. Definition
  2. Standard implementations
  3. Derivation rules
  4. Usage examples

Summary

TraitPurposeDerivable
PrintableString conversionYes
DefaultZero/empty valuesYes (structs only)
TraceableError tracesNo