YREA-SLS/docs/trait_system.md

214 lines
6.1 KiB
Markdown

## 9. Trait System
### 9.1 What are Traits
Traits define behavioral contracts - they specify what operations a type must support without dictating how those operations are implemented.
**Why Traits Exist**:
- Define common behavior across different types
- Enable generic programming with constraints
- Back every operator in the language
- Allow user-defined operators through trait implementation
**Standard Traits Overview**:
The language provides many built-in traits:
- `::Stackable` - Stack manipulation operations
- `::Addable`, `::Multiplyable` - Arithmetic operations
- `::Comparable`, `::Equatable` - Comparison operations
- `::Logical`, `::Bitwise` - Boolean and bit operations
- `::Sized`, `::Selectable<T>`, `::Sliceable` - Container operations
- `::Number` - Composite numeric operations
- And many more...
> **Complete Reference**: See Appendix B for all standard trait definitions with complete documentation.
### 9.2 Defining Traits
**Syntax**: `{ method_signatures } ::identifier<type_params>? trait`
Traits can have methods or be empty (marker traits). Empty traits are typically used with inheritance.
**Examples**:
```
// Trait with methods
{
(Self -- ) draw:
} ::Drawable trait
// Trait with multiple methods
{
(Self Self -- Self) add:
(Self Self -- Self) sub:
(Self -- Self) neg:
} ::Numeric trait
// Generic trait
{
(Self T -- Self) append:
(Self -- T) pop:
} ::Container<T> trait
// Empty marker trait
{ } ::Serializable trait
```
**Method Signatures**: Within the TokenString, identifiers are method names and should not use the `::` prefix.
### 9.3 Implementing Traits
**Syntax**: `::trait_identifier { method_implementations } ::type_identifier impl`
**Implementation Rules**:
1. Implementing a trait for itself (`::Trait { ... } ::Trait impl`) creates a default implementation for all types
2. A trait must be defined before it can be implemented
3. Method implementations can be split across multiple `impl` blocks
4. Later implementations can override earlier ones for the same type
**Examples**:
```
// Implement Addable for i32
::Addable {
(Self Self -- Self) {
// Native addition implementation
} +:
(Self Self -- Self) {
// Native subtraction implementation
} -:
} ::i32 impl
// Implement Drawable for Rectangle
::Drawable {
(Self -- ) {
"Drawing rectangle" print
dup ::width get print
::height get print
} draw:
} ::Rectangle impl
```
> **More Examples**: See Appendix G for complete implementation examples and tutorials.
### 9.4 Trait Inheritance
**Syntax**: `[ identifier_list ] ::identifier<type_params>? inher { methods } ::identifier<type_params>? trait`
Trait inheritance allows a trait to include all methods from parent traits, optionally adding new methods.
**Examples**:
```
// Combine multiple arithmetic traits
[ ::Addable ::Multiplyable ] ::BasicNumber inher
{ } ::BasicNumber trait
// Full Number inherits everything numeric
[ ::Addable ::Multiplyable ::Exponentiable ::Comparable ::Logarithmic ] ::Number inher
{ } ::Number trait
// Inheritance with additional methods
[ ::Drawable ::Transformable ::Collidable ] ::GameObject inher
{
(Self -- ) update:
(Self -- ) destroy:
} ::GameObject trait
```
**Generic Trait Inheritance**:
When inheriting from generic traits, you must either make the inheriting trait similarly generic or specify concrete types:
```
// Inheriting trait is also generic
[ ::Container<T> ] ::Stack<T> inher
{
(Self -- T) pop:
} ::Stack<T> trait
// Inheriting trait specifies concrete type
[ ::Container<i32> ] ::IntStack inher
{
(Self -- i32) pop:
} ::IntStack trait
```
### 9.5 Using Traits in Functions
Traits can be used as type constraints in function signatures:
**Examples**:
```
// Function requiring Drawable trait
(Drawable -- ) {
draw
} ::draw_object fn
// Function requiring Number trait
(Number Number -- Number) {
dup * swap dup * + // Pythagorean: a² + b²
} ::sum_of_squares fn
// Generic function with trait constraint
(Multiplyable -- Multiplyable) {
dup *
} ::square fn
```
**Multiple Constraints**: Use specific traits or composite traits that inherit from multiple parents:
```
// Requires both Addable and Comparable
(Number -- Number) { ... } ::some_function fn
// Number trait inherits from both, so this works
```
### 9.6 Standard Traits Overview
This section provides a brief overview of all standard traits. For complete definitions with all methods and documentation, see Appendix B.
**Stack Operations**:
- `::Stackable` - Fundamental stack manipulation (dup, drop, swap, over, rot, pick, roll, depth)
**Arithmetic**:
- `::Addable` - Addition and subtraction (+, -)
- `::Multiplyable` - Multiplication, division, modulo (*, /, %)
- `::Exponentiable` - Exponentiation (^)
- `::Logarithmic` - Logarithm operations (log, ln, logb)
- `::Number` - Composite trait combining all arithmetic and comparison
**Comparison**:
- `::Orderable` - Ordering comparisons (>, >=, <, <=)
- `::Equatable` - Equality comparisons (==, !=)
- `::Comparable` - Composite trait combining Orderable and Equatable
**Logical and Bitwise**:
- `::Logical` - Boolean operations (and, or, not, truthy)
- `::Bitwise` - Bit manipulation (bitand, bitor, bitxor, bitnot, shl, shr)
**Containers**:
- `::Sized` - Length information (length)
- `::Selectable<T>` - Element access (at)
- `::Sliceable` - Slicing operations (slice)
- `::Concatenable` - Concatenation (concat)
- `::ArrayOf<T>` - Composite array trait
- `::Iterable<T>` - Iteration support (next)
**Conversion**:
- `::Convertible` - Type conversions (to_i8, to_i16, ..., to_f32, to_f64)
- `::Stringifiable` - String conversion (to_str)
- `::Parseable` - Parse from string (parse)
**String Operations**:
- `::String` - String-specific operations (substr, split) - inherits from Concatenable
**Utilities**:
- `::Size` - Types suitable for indexing (inherits Addable, Comparable, Convertible)
- `::Identifier` - Marks identifiers
- `::Implementable` - Meta-trait for defining language constructs (trait, impl, inher)
> **Complete Reference**: See Appendix B for full trait definitions with all methods, examples, and implementation details.
---