Skip to content

Volume 16: Memory Model

1. Introduction

This volume defines the source-level memory model in the Rethon programming language. It describes the memory safety model, ownership transparency, value semantics, reference semantics, struct memory behavior, class memory behavior, assignment and passing, copying, aliasing, lifetime guarantees, automatic memory management, async memory safety, error handling and cleanup, FFI considerations, deferred weak references, deferred move semantics, deferred borrowing, deferred destructors and deinitializers, deferred unsafe memory operations, future extensions, and summary.

This document is part of the official Rethon Language Specification. It is normative rather than descriptive. Implementations, tooling, documentation systems, and other source-processing tools shall treat the rules in this volume as authoritative.

This volume does not define backend allocation algorithms, reference-counting mechanics, tracing behavior, ABI details, or runtime-specific memory-management internals. It defines the source-level and language-level guarantees that implementations shall preserve.

Rethon is Python-inspired in language philosophy and Python-first in surface syntax where practical. It is statically typed, AOT compiled, memory-safe by default, and ownership-transparent.

Rethon uses memory safety by default, ownership transparency for ordinary code, structs as value types, classes as reference types, automatic memory management, no manual memory management in ordinary code, implementation flexibility across ARC, RC, GC, or hybrid strategies, and deferred unsafe and ownership-heavy features.

2. Memory Safety Model

Rethon shall be memory-safe by default.

Ordinary application code shall not be required to use manual memory management.

Memory safety shall be a language-level guarantee rather than an optional library convention.

The language shall define behavior in terms of visible source-level guarantees and shall not require ordinary code to reason about raw allocation and deallocation mechanics.

Example:

struct Point:
    x: int
    y: int

let point = Point(x: 1, y: 2)

A well-typed ordinary program shall not need unsafe memory operations to express standard application logic.

3. Ownership Transparency

Ownership and lifetime details shall be transparent enough for implementation and tooling, but they shall remain hidden from ordinary source-level programming.

The programmer-facing model shall remain readable and high level.

Ordinary code shall not need to spell out retain/release behavior, manual ownership transfers, or borrow annotations.

Ownership transparency shall preserve the language's Python-first surface direction while allowing efficient implementation strategies.

The source language shall therefore define guarantees, not low-level ownership choreography.

4. Value Semantics

Value semantics shall apply to value types.

Structs shall be value types.

A value type shall be treated as an independent value rather than as a shared identity-bearing object.

Copying, passing, and returning a value type shall preserve value meaning.

Example:

struct Point:
    x: int
    y: int

let a = Point(x: 1, y: 2)
let b = a

The bindings a and b shall denote equal values of the same struct type.

Value semantics shall remain compatible with compiler optimizations that avoid unnecessary physical copying as long as the observable value meaning remains correct.

5. Reference Semantics

Reference semantics shall apply to reference types.

Classes shall be reference types.

A reference type shall refer to an identity-bearing object.

Copying, passing, and returning a reference type shall preserve reference meaning rather than create a new independent object.

Example:

class Logger:
    pass

let first = Logger()
let second = first

The bindings first and second shall refer to the same object.

Reference semantics shall allow shared mutable state when that state is semantically appropriate.

Reference semantics shall not force ordinary source code to expose backend ownership mechanics.

6. Struct Memory Behavior

Structs shall use value semantics.

A struct shall represent data by value rather than by identity.

A struct shall be suitable for ordinary data modeling, records, and other value-oriented abstractions.

A struct shall not imply shared object identity by default.

A struct may contain fields whose own types are values or references, but the struct itself shall remain a value type.

Example:

struct UserRecord:
    name: str
    session: Session?

The struct's value semantics shall remain visible at the source level even when its fields include reference-bearing values.

7. Class Memory Behavior

Classes shall use reference semantics.

A class shall represent identity-bearing objects whose lifetime, shared state, or object identity is semantically important.

A class shall be appropriate for services, resources, caches, coordinators, and other identity-oriented abstractions.

Example:

class Session:
    id: str

A class value shall refer to the same object when assigned or passed to another binding or function.

A class shall not imply value semantics by default.

8. Assignment and Passing

Assignment shall preserve the semantics of the assigned type.

Assigning a struct value shall preserve value semantics.

Assigning a class value shall copy the reference.

Passing a struct value to a function shall preserve value semantics.

Passing a class value to a function shall preserve reference semantics.

Returning a struct value shall preserve value semantics.

Returning a class value shall preserve reference semantics.

Example:

def use_point(point: Point) -> Point:
    return point

class Session:
    pass

def use_session(session: Session) -> Session:
    return session

The source model shall therefore distinguish value transfer from reference transfer without requiring ordinary code to expose low-level ownership operations.

9. Copying

Copying shall be understood according to type semantics.

Copying a struct value shall produce another value with the same observable value meaning.

Copying a class value shall copy the reference, not duplicate the object.

Copying shall not require the programmer to distinguish physical duplication from semantic duplication in ordinary code.

Example:

let original = Point(x: 1, y: 2)
let duplicate = original

For value types, the result shall be an independent value.

For reference types, the result shall refer to the same object.

10. Aliasing

Aliasing shall be allowed.

Multiple bindings may refer to the same value or object depending on the type's semantics.

Aliasing of value types shall preserve value meaning.

Aliasing of reference types shall preserve shared identity.

The language shall not require ordinary code to model aliasing with manual ownership annotations.

Example:

let first = Session()
let alias = first

Aliasing shall be a source-level semantic fact, not a manual memory-management burden for ordinary code.

11. Lifetime Guarantees

The language shall provide source-level lifetime guarantees sufficient for memory safety and ordinary resource usage.

Ordinary code shall not be required to manage object lifetime manually.

Ownership and lifetime details shall be hidden from ordinary code while remaining available to the implementation and tooling as needed to preserve safety.

The specification does not commit to a specific lifetime representation.

The language shall prevent ordinary source code from observing invalid memory through well-typed safe operations.

12. Automatic Memory Management

The implementation may use automatic memory management techniques including reference counting, ARC, tracing GC, or a hybrid strategy.

The specification shall define visible guarantees rather than prescribing one fixed implementation mechanism.

The implementation may choose the strategy or combination of strategies that best satisfies the language's safety and performance goals.

The source language shall not expose retain/release operations as part of the ordinary model.

Ordinary code shall not depend on the specific automatic memory strategy chosen by the implementation.

13. Async Memory Safety

Async suspension shall not invalidate safe references or violate memory safety guarantees.

Example:

async def load_and_use(session: Session) -> None:
    await refresh_session(session)
    print(session.id)

Async code shall preserve the same source-level memory guarantees as synchronous code.

Suspension points shall not expose partially invalid state to ordinary source code.

The async model shall remain compatible with the memory model established in this volume.

14. Error Handling and Cleanup

Error handling shall not leak unsafe partial state into ordinary source-level behavior.

try, except, finally, raise, Result<T, E>, and Option<T> shall remain compatible with the memory model.

A finally clause shall be the initial source-level cleanup form.

Example:

try:
    resource = open_resource()
    ...
finally:
    resource.close()

Cleanup behavior shall remain explicit in source code.

The specification does not define a separate destructor model in this volume.

15. FFI Considerations

Foreign-function interface memory details shall be deferred to the FFI volume or another later specification document.

This volume does not define foreign ownership transfer, foreign reference lifetime rules, or interop-specific allocation strategy.

FFI behavior shall be specified separately so that native interoperability can evolve without changing the source-level memory model defined here.

16. Deferred Weak References

Weak references shall be deferred.

The initial memory model shall not require weak-reference syntax or semantics in the core language.

Weak references may be introduced later if they are justified by the memory model, the standard library, or interoperability needs.

17. Deferred Move Semantics

Move semantics shall be deferred.

The initial language model shall not require Rust-style ownership transfer or move-only programming as an ordinary source-level discipline.

The language may revisit move semantics later if they become useful for specialized performance or safety goals.

18. Deferred Borrowing

Borrowing shall be deferred.

The initial language model shall not require borrow checking or explicit borrow annotations in ordinary code.

Borrowing may be introduced later only if it can be integrated cleanly with the language's Python-first surface direction and ownership-transparent ordinary programming model.

19. Deferred Destructors and Deinitializers

Destructors and deinitializers shall be deferred until the lifecycle model matures.

The language shall not finalize destructor syntax or destructor semantics in this volume.

If later specification work introduces destructor-like behavior, it shall be defined in a way that preserves memory safety, source readability, and the existing ownership-transparent model.

20. Deferred Unsafe Memory Operations

Unsafe memory operations shall be deferred and isolated into future explicit unsafe features.

Ordinary code shall remain safe by default.

If the language later introduces unsafe memory primitives, those primitives shall be explicit, isolated, and clearly separated from the safe ordinary model.

Unsafe operations shall not become part of ordinary source-level programming.

21. Future Extensions

This volume defines the current direction for memory in Rethon, but future specification work may refine the model in carefully controlled ways.

Possible future extensions include:

  • more precise lifecycle rules
  • more explicit FFI ownership contracts
  • weak references
  • move semantics
  • borrowing
  • destructor and deinitializer semantics
  • explicit unsafe memory features
  • specialized optimization guidance for implementations

Any future extension shall preserve the current direction:

  • memory safety remains the default
  • ordinary code remains ownership-transparent
  • structs remain value types
  • classes remain reference types
  • automatic memory management remains implementation-flexible
  • retain/release remain hidden from ordinary source code
  • weak references, move semantics, borrowing, destructors, and unsafe memory operations remain deferred until justified

22. Summary

Rethon shall provide memory safety by default.

Ordinary code shall not require manual memory management.

Ownership and lifetime details shall remain transparent to the implementation while staying hidden from ordinary source-level programming.

Structs shall use value semantics, and classes shall use reference semantics.

Assignment, passing, returning, copying, and aliasing shall preserve the semantics of the underlying type form.

The implementation may use ARC, RC, GC, or a hybrid strategy, but the source language shall not prescribe one internal mechanism or expose retain/release in ordinary code.

Weak references, move semantics, borrowing, destructors, and unsafe memory operations shall remain deferred and isolated for future refinement.

The memory model in Rethon shall therefore remain safe, readable, ownership-transparent, and compatible with the language's Python-first surface direction.