219 lines
6.3 KiB
Markdown
219 lines
6.3 KiB
Markdown
---
|
|
Title: 9 Trait System
|
|
Prev: Type System
|
|
Next: Generic Programming
|
|
---
|
|
|
|
## 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](./complete_trait_reference.html) 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](./examples_and_tutorials.html) 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](./complete_trait_reference.html).
|
|
|
|
**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](./complete_trait_reference.html) for full trait definitions with all methods, examples, and implementation details.
|
|
|
|
---
|