Ownership Type System
Implements ownership types with borrowing and lifetimes.
When to Use
- Verifying memory safety
- Preventing data races
- Lifetime analysis
- Resource management
What This Skill Does
- Implements ownership - Each value has single owner
- Handles borrowing - Mutable and immutable references
- Verifies lifetimes - Lexical lifetimes
- Checks borrowing rules - Aliasing XOR mutability
Core Rules
Ownership Rules:
- Each value has exactly one owner
- When owner goes out of scope, value is dropped
- Ownership can be transferred (move)
- Ownership can be borrowed (reference)
Borrowing Rules:
- Either OR many immutable references
- OR exactly one mutable reference
- References must not outlive borrowed data
Implementation
from dataclasses import dataclass, field
from typing import Dict, List, Set, Optional
from enum import Enum
class Ownership(Enum):
OWNED = "owned"
BORROWED_MUT = "borrowed_mut"
BORROWED_IMMUT = "borrowed_immut"
@dataclass
class Type:
"""Ownership type"""
base: str
ownership: Ownership
lifetime: Optional['Lifetime'] = None
@dataclass
class Lifetime:
"""Lifetime region"""
name: str
upper_bound: Optional['Lifetime'] = None
@dataclass
class Variable:
"""Variable with ownership info"""
name: str
typ: Type
is_mutable: bool
@dataclass
class Borrow:
"""Borrow expression"""
borrower: str # Variable doing borrowing
lender: str # Variable being borrowed
is_mutable: bool
lifetime: Lifetime
class OwnershipChecker:
"""Check ownership and borrowing"""
def __init__(self):
self.variables: Dict[str, Variable] = {}
self.borrows: List[Borrow] = []
self.errors: List[str] = []
def check_program(self, program: 'Program') -> bool:
"""Check ownership rules"""
self.variables = {}
self.borrows = []
self.errors = []
for stmt in program.statements:
self.check_statement(stmt)
return len(self.errors) == 0
def check_statement(self, stmt: 'Stmt'):
"""Check single statement"""
match stmt:
case Let(x, typ, value):
# Register owned variable
self.variables[x] = Variable(x, typ, False)
case Move(x, y):
# Transfer ownership
if y in self.variables:
# Check no active borrows
active = [b for b in self.borrows if b.lender == y]
if active:
self.errors.append(
f"Cannot move '{y}': has {len(active)} active borrows"
)
# Transfer ownership
self.variables[x] = self.variables.pop(y)
case BorrowRef(x, y, mutable):
# Create borrow
if y not in self.variables:
self.errors.append(f"Cannot borrow undeclared variable: {y}")
return
lender = self.variables[y]
# Check aliasing XOR mutability
existing_borrows = [b for b in self.borrows if b.lender == y]
if mutable:
# Cannot have other borrows
if existing_borrows:
self.errors.append(
f"Cannot mutably borrow '{y}': already borrowed"
)
# Cannot be borrowed mutably if already mutable
if lender.is_mutable:
self.errors.append(
f"Cannot mutably borrow already mutable variable: {y}"
)
else:
# Check no mutable borrows
mutable_borrows = [b for b in existing_borrows if b.is_mutable]
if mutable_borrows:
self.errors.append(
f"Cannot immutably borrow '{y}': already mutably borrowed"
)
# Record borrow
borrow = Borrow(x, y, mutable, Lifetime("scope"))
self.borrows.append(borrow)
# Register borrower
self.variables[x] = Variable(x, Type(lender.typ.base,
Ownership.BORROWED_MUT if mutable else Ownership.BORROWED_IMMUT), mutable)
case Assign(x, y):
# Check not assigning to borrowed
if x in self.variables:
x_var = self.variables[x]
if x_var.typ.ownership != Ownership.OWNED:
self.errors.append(f"Cannot assign to borrowed variable: {x}")
case Drop(x):
# Check no active borrows
if x in self.variables:
active = [b for b in self.borrows if b.lender == x]
if active:
self.errors.append(
f"Cannot drop '{x}': has {len(active)} active borrows"
)
del self.variables[x]
def check_lifetime(self, borrow: Borrow, lender_var: Variable) -> bool:
"""Check borrow lifetime"""
if borrow.lifetime and lender_var.typ.lifetime:
# Borrow lifetime must be <= lender lifetime
return self.lifetime_sub(borrow.lifetime, lender_var.typ.lifetime)
return True
def lifetime_sub(self, sub: Lifetime, sup: Lifetime) -> bool:
"""Check sub ≤ sup"""
# Simplified: lexical scoping
return True
# Example programs
def examples():
"""
Valid:
let x = Vec::new();
let y = &x; // immutable borrow
let z = &x; // multiple immutable OK
Invalid:
let x = Vec::new();
let y = &mut x; // mutable borrow
let z = &x; // immutable after mutable
Move semantics:
let x = Vec::new();
let y = x; // x moved to y
// x no longer valid
"""
pass
Key Concepts
| Concept |
Description |
| Ownership |
Single owner per value |
| Borrow |
Temporary reference |
| Move |
Transfer ownership |
| Lifetime |
Region of validity |
| Borrow checking |
Aliasing XOR mutability |
Rust Borrowing Rules
Rules:
1. &T: Multiple immutable references OK
2. &mut T: Only one mutable reference
3. No references to references (directly)
4. &mut only from owned or &mut
5. Lifetime: borrow must not outlive lender
Tips
- Track active borrows
- Handle drops correctly
- Check lifetime relationships
- Consider interior mutability
Related Skills
linear-type-implementer - Linear types
garbage-collector-implementer - GC
type-checker-generator - Type checking
Canonical References
| Reference |
Why It Matters |
| Clarke, Potter, Noble, "Ownership Types for Flexible Alias Protection" (OOPSLA 1998) |
Original ownership types paper |
| Noble, Vitek, Potter, "Flexible Alias Protection" (ECOOP 1998) |
Conceptual foundation for ownership types |
| Boyland, "Alias Burying: Unique Variables Without Destructive Reads" (2001) |
Uniqueness without destructive reads |
| Tofte & Talpin, "Region-Based Memory Management" (Information and Computation, 1997) |
Region-based memory for ML |
| Clarke, Drossopoulou, "Ownership, Encapsulation and the Disjointness of Type and Effect" (OOPSLA 2002) |
Ownership and effects |
Tradeoffs and Limitations
Ownership Approach Tradeoffs
| Approach |
Pros |
Cons |
| Rust-style |
Safe, no GC |
Complexity |
| Regions |
Fast |
Complex regions |
| Unique pointers |
Simple |
Limited |
| Capabilities |
Flexible |
Hard to use |
When NOT to Use Ownership Types
- For simple programs: GC is simpler
- For rapid prototyping: Ownership adds overhead
- For shared state: Use Arc/Rc instead
Complexity Considerations
- Borrow checking: O(n) per borrow
- Lifetimes: Can require annotations
- Error messages: Complex to explain
Limitations
- Learning curve: Complex rules to learn
- Error messages: Can be cryptic
- Interior mutability: Requires special handling (Cell, RefCell)
- Lifetimes: Must be explicit or inferred
- Async: Lifetimes with async complex
- Interoperability: FFI complexity
- Shared ownership: Not zero-cost
Research Tools & Artifacts
Ownership systems:
| System |
What to Learn |
| Rust |
Ownership/borrowing |
| PyOxygen |
Ownership in Python |
Research Frontiers
1. Linear Types in Haskell
Implementation Pitfalls
| Pitfall |
Real Consequence |
Solution |
| Borrow errors |
Rejected programs |
Learn patterns |
Converted and distributed by TomeVault — claim your Tome and manage your conversions.
1---2name: rainoftime-pl-skills-ownership-type-system3description: Ownership Type System4---56# Ownership Type System78Implements ownership types with borrowing and lifetimes.910## When to Use1112- Verifying memory safety13- Preventing data races14- Lifetime analysis15- Resource management1617## What This Skill Does18191. **Implements ownership** - Each value has single owner202. **Handles borrowing** - Mutable and immutable references213. **Verifies lifetimes** - Lexical lifetimes224. **Checks borrowing rules** - Aliasing XOR mutability2324## Core Rules2526```27Ownership Rules:28 - Each value has exactly one owner29 - When owner goes out of scope, value is dropped30 - Ownership can be transferred (move)31 - Ownership can be borrowed (reference)3233Borrowing Rules:34 - Either OR many immutable references35 - OR exactly one mutable reference36 - References must not outlive borrowed data37```3839## Implementation4041```python42from dataclasses import dataclass, field43from typing import Dict, List, Set, Optional44from enum import Enum4546class Ownership(Enum):47 OWNED = "owned"48 BORROWED_MUT = "borrowed_mut"49 BORROWED_IMMUT = "borrowed_immut"5051@dataclass52class Type:53 """Ownership type"""54 base: str55 ownership: Ownership56 lifetime: Optional['Lifetime'] = None5758@dataclass59class Lifetime:60 """Lifetime region"""61 name: str62 upper_bound: Optional['Lifetime'] = None6364@dataclass65class Variable:66 """Variable with ownership info"""67 name: str68 typ: Type69 is_mutable: bool7071@dataclass72class Borrow:73 """Borrow expression"""74 borrower: str # Variable doing borrowing75 lender: str # Variable being borrowed76 is_mutable: bool77 lifetime: Lifetime7879class OwnershipChecker:80 """Check ownership and borrowing"""81 82 def __init__(self):83 self.variables: Dict[str, Variable] = {}84 self.borrows: List[Borrow] = []85 self.errors: List[str] = []86 87 def check_program(self, program: 'Program') -> bool:88 """Check ownership rules"""89 90 self.variables = {}91 self.borrows = []92 self.errors = []93 94 for stmt in program.statements:95 self.check_statement(stmt)96 97 return len(self.errors) == 098 99 def check_statement(self, stmt: 'Stmt'):100 """Check single statement"""101 102 match stmt:103 case Let(x, typ, value):104 # Register owned variable105 self.variables[x] = Variable(x, typ, False)106 107 case Move(x, y):108 # Transfer ownership109 if y in self.variables:110 # Check no active borrows111 active = [b for b in self.borrows if b.lender == y]112 if active:113 self.errors.append(114 f"Cannot move '{y}': has {len(active)} active borrows"115 )116 117 # Transfer ownership118 self.variables[x] = self.variables.pop(y)119 120 case BorrowRef(x, y, mutable):121 # Create borrow122 if y not in self.variables:123 self.errors.append(f"Cannot borrow undeclared variable: {y}")124 return125 126 lender = self.variables[y]127 128 # Check aliasing XOR mutability129 existing_borrows = [b for b in self.borrows if b.lender == y]130 131 if mutable:132 # Cannot have other borrows133 if existing_borrows:134 self.errors.append(135 f"Cannot mutably borrow '{y}': already borrowed"136 )137 # Cannot be borrowed mutably if already mutable138 if lender.is_mutable:139 self.errors.append(140 f"Cannot mutably borrow already mutable variable: {y}"141 )142 else:143 # Check no mutable borrows144 mutable_borrows = [b for b in existing_borrows if b.is_mutable]145 if mutable_borrows:146 self.errors.append(147 f"Cannot immutably borrow '{y}': already mutably borrowed"148 )149 150 # Record borrow151 borrow = Borrow(x, y, mutable, Lifetime("scope"))152 self.borrows.append(borrow)153 154 # Register borrower155 self.variables[x] = Variable(x, Type(lender.typ.base, 156 Ownership.BORROWED_MUT if mutable else Ownership.BORROWED_IMMUT), mutable)157 158 case Assign(x, y):159 # Check not assigning to borrowed160 if x in self.variables:161 x_var = self.variables[x]162 if x_var.typ.ownership != Ownership.OWNED:163 self.errors.append(f"Cannot assign to borrowed variable: {x}")164 165 case Drop(x):166 # Check no active borrows167 if x in self.variables:168 active = [b for b in self.borrows if b.lender == x]169 if active:170 self.errors.append(171 f"Cannot drop '{x}': has {len(active)} active borrows"172 )173 del self.variables[x]174 175 def check_lifetime(self, borrow: Borrow, lender_var: Variable) -> bool:176 """Check borrow lifetime"""177 178 if borrow.lifetime and lender_var.typ.lifetime:179 # Borrow lifetime must be <= lender lifetime180 return self.lifetime_sub(borrow.lifetime, lender_var.typ.lifetime)181 182 return True183 184 def lifetime_sub(self, sub: Lifetime, sup: Lifetime) -> bool:185 """Check sub ≤ sup"""186 187 # Simplified: lexical scoping188 return True189190# Example programs191def examples():192 """193 Valid:194 let x = Vec::new();195 let y = &x; // immutable borrow196 let z = &x; // multiple immutable OK197 198 Invalid:199 let x = Vec::new();200 let y = &mut x; // mutable borrow201 let z = &x; // immutable after mutable202 203 Move semantics:204 let x = Vec::new();205 let y = x; // x moved to y206 // x no longer valid207 """208 pass209```210211## Key Concepts212213| Concept | Description |214|---------|-------------|215| **Ownership** | Single owner per value |216| **Borrow** | Temporary reference |217| **Move** | Transfer ownership |218| **Lifetime** | Region of validity |219| **Borrow checking** | Aliasing XOR mutability |220221## Rust Borrowing Rules222223```224Rules:2251. &T: Multiple immutable references OK2262. &mut T: Only one mutable reference2273. No references to references (directly)2284. &mut only from owned or &mut2295. Lifetime: borrow must not outlive lender230```231232## Tips233234- Track active borrows235- Handle drops correctly236- Check lifetime relationships237- Consider interior mutability238239## Related Skills240241- `linear-type-implementer` - Linear types242- `garbage-collector-implementer` - GC243- `type-checker-generator` - Type checking244245## Canonical References246247| Reference | Why It Matters |248|-----------|----------------|249| **Clarke, Potter, Noble, "Ownership Types for Flexible Alias Protection" (OOPSLA 1998)** | Original ownership types paper |250| **Noble, Vitek, Potter, "Flexible Alias Protection" (ECOOP 1998)** | Conceptual foundation for ownership types |251| **Boyland, "Alias Burying: Unique Variables Without Destructive Reads" (2001)** | Uniqueness without destructive reads |252| **Tofte & Talpin, "Region-Based Memory Management" (Information and Computation, 1997)** | Region-based memory for ML |253| **Clarke, Drossopoulou, "Ownership, Encapsulation and the Disjointness of Type and Effect" (OOPSLA 2002)** | Ownership and effects |254255## Tradeoffs and Limitations256257### Ownership Approach Tradeoffs258259| Approach | Pros | Cons |260|----------|------|------|261| **Rust-style** | Safe, no GC | Complexity |262| **Regions** | Fast | Complex regions |263| **Unique pointers** | Simple | Limited |264| **Capabilities** | Flexible | Hard to use |265266### When NOT to Use Ownership Types267268- **For simple programs**: GC is simpler269- **For rapid prototyping**: Ownership adds overhead270- **For shared state**: Use Arc/Rc instead271272### Complexity Considerations273274- **Borrow checking**: O(n) per borrow275- **Lifetimes**: Can require annotations276- **Error messages**: Complex to explain277278### Limitations279280- **Learning curve**: Complex rules to learn281- **Error messages**: Can be cryptic282- **Interior mutability**: Requires special handling (Cell, RefCell)283- **Lifetimes**: Must be explicit or inferred284- **Async**: Lifetimes with async complex285- **Interoperability**: FFI complexity286- **Shared ownership**: Not zero-cost287288## Research Tools & Artifacts289290Ownership systems:291292| System | What to Learn |293|--------|---------------|294| **Rust** | Ownership/borrowing |295| **PyOxygen** | Ownership in Python |296297## Research Frontiers298299### 1. Linear Types in Haskell300- **Approach**: Linear Haskell301302## Implementation Pitfalls303304| Pitfall | Real Consequence | Solution |305|---------|-----------------|----------|306| **Borrow errors** | Rejected programs | Learn patterns |307308---309> Converted and distributed by [TomeVault](https://tomevault.io/claim/rainoftime) — claim your Tome and manage your conversions.310<!-- tomevault:4.0:skill_md:2026-04-11 -->