YREA-SLS/stack_lang_spec.md

99 KiB

Stack Language Specification

Version: 0.8
Status: Draft Specification
Changes:

  • 0.5 (AI)
    1. Escape sequences - Added a complete list of escape sequences for string literals
    2. Type Tuples - Defined them as function signatures representing stack effects
    3. Control flow TokenStrings - Clarified that if, while, match, etc. use TokenStrings
    4. Generic constructs - Clarified that generics need trait constraints when operations are performed
    5. Stack manipulation traits - Combined into a single Stackable trait
    6. Size trait - Added proper definition inheriting from Addable, Comparable, and Convertible
    7. Empty traits - Clarified that traits can be empty (especially when used with inheritance)
    8. Trait inheritance - Fixed syntax to require both inher and trait declarations
    9. Array combinators - Clarified that the functions inside parse their TokenStrings
    10. :: in TokenStrings - Clarified it should NOT be used in trait/impl contexts
  • 0.5.1 (Human)
    1. Created TODOs
    2. Made various corrections (not everything was corrected)
    3. Reviewed and corrected some code blocks
    4. Made a few adjustments manually
  • 0.6 (AI)
    1. Operator descriptions - Added natural language descriptions for all built-in operators
    2. Operators vs Functions - Clarified distinction and naming rules
    3. Generic trait syntax - Documented <> syntax for generic traits
    4. Generic trait inheritance - Clarified rules for inheriting from generic traits
    5. Code block types - Distinguished actual language definitions from examples
    6. Trait appendix - Created comprehensive trait definitions appendix
    7. TokenString contexts - Listed all control flow operators and their parsing behavior
    8. Lambda operator - Added specification for lambda operator
    9. Type parameter enforcement - Documented current parsing behavior
    10. Identifier literal requirements - Specified :: rules for different contexts
    11. Trait implementation rules - Clarified implementation semantics
    12. Type conversions - Changed to explicit conversion functions
    13. Memory management - Moved to appendix as future feature
    14. Module system - Added appendix entry for future imports
    15. Examples section - Moved to appendix
    16. Syntax summary - Moved to appendix and expanded
  • 0.6.1 (AI)
    1. Variadic arguments - Decision: Use array syntax for variable arguments (no special variadic syntax yet)
    2. Inheritance before trait - Decision: Yes, inheritance declarations must come before trait definition
    3. inher operator - Decision: No, merge inheritance into trait operator (removed inher)
    4. Separate inher vs impl - Decision: Keep them separate (impl is for implementations only)
  • 0.6.2 (Human)
    1. Created TODOs
    2. Made various corrections (not everything was corrected)
    3. Reviewed and corrected some code blocks
    4. Made a few adjustments manually
    5. Reversed removing inher
  • 0.7 (AI)
    1. Operator definition - Clarified that operators can be user/library defined via trait implementation
    2. Generic function syntax - Fixed to use trait constraints in type tuple, not generic parameters
    3. Variable arguments with Iterable - Changed array syntax to Iterable trait for variable args
    4. Example classifications - Cleaned up "Actual Language Definitions" vs examples distinction
    5. Struct field access - Clarified that get and set consume their arguments
    6. Section 6 rename - Renamed "Operators (Postfix)" to "Built-in Operators"
    7. Module syntax - Added :: prefix for module imports
    8. Module alias options - Added multiple alias syntax options
  • 0.7.1 (Human)
    1. Formatting changes
  • 0.7.2 (Human)
    1. Removed AI editing restrictions of reviewed code blocks
  • 0.8 (AI)
    1. Document reorganization - Restructured for user-focused learning
    2. Section consolidation - Moved implementation details to appendices
    3. Minimal duplication - Added cross-references instead of repeating content
    4. Shorter sections - Split large sections into focused subsections
    5. New appendices - Added Standard Library and Operator references
    6. Tutorial content - Added beginner tutorials to Appendix G
    7. Trait reference - Consolidated all trait definitions in Appendix B
    8. Grammar simplification - Referenced Implementable trait instead of repeating

1. Overview

A statically-typed, stack-based language with pure postfix notation combining the execution model of HP's RPL, the type system of C and Rust, and modern array operations from Uiua.

Design Principles

  • Everything is postfix - no exceptions
  • Stack-based execution (no local variables)
  • Static typing with type inference
  • Manual heap memory management (future feature)
  • Types define what things are, traits define how things act
  • All constructs are implicitly generic
  • Every operator is defined by a trait

Operators vs Functions

Operators are operations that implement trait methods. They can be:

  • Built-in primitive operations provided by the language
  • User-defined operations implementing custom trait methods
  • Library-defined operations
  • All operators must be backed by a trait
  • Cannot share names with functions
  • Are the fundamental building blocks of the language
  • Examples: +, -, dup, swap, if, while (built-in); custom operators via trait implementation

Functions are user-defined or library-defined procedures. They:

  • Do not implement traits directly (though they may use operators that do)
  • Cannot share names with operators
  • Are defined using the fn operator
  • Examples: factorial, fizzbuzz, square

Naming Rule: Once a name is used for either an operator or a function, it cannot be reused for the other category.

Document Organization

This specification is organized to support both learning and reference:

Sections 1-7 cover the fundamentals needed to write basic programs:

  • Lexical structure, primitive types, basic operations
  • Functions and control flow
  • Data structures

Sections 8-10 cover intermediate concepts:

  • Type system formalization
  • Trait system for behavioral contracts
  • Generic programming

Section 11 covers advanced topics:

  • Dynamic code evaluation
  • Identifier literals
  • Standard library overview

Appendices provide complete references:

  • A: Standard Library (alphabetical reference)
  • B: Complete Trait Reference (all trait definitions)
  • C: Complete Operator Reference (all operators)
  • D: Grammar Summary
  • E: Module System (future)
  • F: Memory Management (future)
  • G: Examples & Tutorials

Reading Guide

New users: Start with Sections 1-7 to learn the language basics. Work through the tutorials in Appendix G as you go.

Experienced programmers: Skim Sections 1-4, focus on Sections 5-11 for language-specific features.

Implementers: Read all sections, paying special attention to Sections 8-10 and Appendices B-D for complete specifications.

Reference lookup: Use Appendices A-C for quick reference to standard library functions, traits, and operators.


2. Lexical Structure

2.1 Comments

// Single-line comment

2.2 Identifiers

Regular Identifiers

  • Start with letter or underscore: [a-zA-Z_][a-zA-Z0-9_]*
  • Case-sensitive
  • When encountered, identifiers are executed immediately

Identifier Literals

  • Prefix with :: to push the identifier itself onto the stack instead of executing it
  • Syntax: ::name pushes the identifier name as a value
  • Example: ::Addable pushes the identifier Addable onto the stack
  • Example: ::Point pushes the identifier Point onto the stack

Advanced Usage: See Section 11.2 for complete identifier literal rules and context-dependent behavior.

2.3 Literals

Integer Literals

42          // i64 (default)
42:i32      // Annotate as i32
0xFF        // hexadecimal
0b1010      // binary

Floating Point Literals

3.14        // f64 (default)
3.14:f32    // Annotate as f32

String Literals

"hello world"
"escape sequences: \n \t \\ \""

Escape Sequences

  • \n - Newline (LF)
  • \r - Carriage return (CR)
  • \t - Tab
  • \\ - Backslash
  • \" - Double quote
  • \' - Single quote
  • \0 - Null character
  • \xNN - Hexadecimal byte (e.g., \x41 for 'A')
  • \u{NNNN} - Unicode code point (e.g., \u{1F600} for 😀)

Boolean Literals

true
false

Array Literals

[1 2 3 4 5]              // array of i32
[1.0 2.0 3.0]            // array of f64
[[1 2] [3 4]]            // 2D array

3. Primitive Types

The language provides several built-in primitive types for common values:

Integer Types

  • i8, i16, i32, i64 - Signed integers (8, 16, 32, 64 bits)
  • u8, u16, u32, u64 - Unsigned integers (8, 16, 32, 64 bits)
  • Default integer literal type: i64

Floating Point Types

  • f32 - Single-precision floating point (32 bits)
  • f64 - Double-precision floating point (64 bits)
  • Default floating point literal type: f64

Other Types

  • bool - Boolean values (true or false)
  • char - Single UTF-8 character

Type Annotations

You can explicitly annotate literal types:

42:i32      // 32-bit integer
3.14:f32    // 32-bit float

Pointer Types

Raw pointers (ptr) are a future feature. See Appendix F for the planned pointer type system.

Related: See Section 8 for the complete type system, including composite types and type inference.


4. Basic Operations

4.1 Stack Operations

Stack manipulation is fundamental to the language. All values exist on the stack, and these operations let you rearrange them.

Basic Manipulation

dup         // ( a -- a a ) Duplicate top item
drop        // ( a -- ) Remove top item
swap        // ( a b -- b a ) Swap top two items
over        // ( a b -- a b a ) Copy second item to top
rot         // ( a b c -- b c a) Rotate top three items

Stack Inspection

depth       // ( -- n ) Push current stack depth
pick        // ( n -- x ) Copy nth item to top (0 = top)
roll        // ( n times -- ) Rotate n items, times times

Stack Effect Notation: Throughout this specification, comments use stack effect notation to show what operations consume and produce. The format is // ( before -- after ) where items on the left of -- are consumed from the stack, and items on the right are produced.

Examples:

5 dup        // => 5 5
5 10 swap    // => 10 5
1 2 3 rot    // => 2 3 1
1 2 3 depth  // => 1 2 3 3

Implementation Details: Stack operations implement the ::Stackable trait. See Appendix B for the complete trait definition.

4.2 Arithmetic Operators

Basic arithmetic operations work on numeric types:

3 4 +       // ( a b -- result ) Addition
10 3 -      // ( a b -- result ) Subtraction
5 6 *       // ( a b -- result ) Multiplication
20 4 /      // ( a b -- result ) Division
17 5 %      // ( a b -- result ) Modulo (remainder)
2 8 ^       // ( a b -- result ) Exponentiation
100 log     // ( a -- result ) Logarithm base 10
2.718 ln    // ( a -- result ) Natural logarithm

Examples:

10 5 +      // => 15
10 3 /      // => 3
10 3 %      // => 1
2 10 ^      // => 1024

Implementation Details: Arithmetic operators implement the ::Addable, ::Multiplyable, ::Exponentiable, and ::Logarithmic traits. See Appendix B for complete trait definitions and Appendix C for the full operator reference.

4.3 Comparison Operators

Comparison operations return boolean values:

5 3 >       // ( a b -- bool ) Greater than
5 3 >=      // ( a b -- bool ) Greater or equal
5 3 <       // ( a b -- bool ) Less than
5 3 <=      // ( a b -- bool ) Less or equal
5 5 ==      // ( a b -- bool ) Equal
5 3 !=      // ( a b -- bool ) Not equal

Examples:

10 5 >      // => true
10 10 ==    // => true
10 5 <      // => false

Implementation Details: Comparison operators implement the ::Orderable and ::Equatable traits. See Appendix B for complete trait definitions.

4.4 Logical Operators

Logical operations work with boolean values and truthiness:

true false and    // ( a b -- result ) Logical AND
true false or     // ( a b -- result ) Logical OR
true not          // ( a -- result ) Logical NOT

Truthiness: Non-boolean values can be tested for truthiness. By default, most values are truthy. Numbers are falsy when zero, Option::None is falsy, Result::Err is falsy.

Examples:

true true and     // => true
true false or     // => true
false not         // => true
5 0 and          // => 0 (falsy)

Implementation Details: Logical operators implement the ::Logical trait. See Appendix B for the complete trait definition and truthiness rules.

4.5 Bitwise Operators

Bitwise operations work on integer types:

0xFF 0x0F bitand     // ( a b -- result ) Bitwise AND
0xFF 0x0F bitor      // ( a b -- result ) Bitwise OR
0xFF 0x0F bitxor     // ( a b -- result ) Bitwise XOR
0xFF bitnot          // ( a -- result ) Bitwise NOT
8 2 shl              // ( a n -- result ) Left shift
8 2 shr              // ( a n -- result ) Right shift

Examples:

0xFF 0x0F bitand    // => 0x0F
0xF0 0x0F bitor     // => 0xFF
0xFF bitnot         // => 0xFFFFFFFFFFFFFF00 (on 64-bit)
4 2 shl             // => 16

Implementation Details: Bitwise operators implement the ::Bitwise trait. See Appendix B for the complete trait definition.


5. Functions

Functions are user-defined procedures that encapsulate reusable code. They are the primary abstraction mechanism in the language.

5.1 What are Functions

Functions differ from operators:

  • Operators implement trait methods and are the fundamental building blocks
  • Functions are user-defined procedures that use operators
  • Operators and functions cannot share names

Related: See Section 1 "Operators vs Functions" for a complete explanation of the distinction.

5.2 Defining Functions

Syntax: (inputs -- outputs) { body } ::name fn

The function signature specifies stack effects (what is consumed and produced), the body contains the implementation, and the name identifies the function.

Examples:

// Simple function - requires Multiplyable trait
(Multiplyable -- Multiplyable) { dup * } ::square fn

// Use it
5 square      // => 25

// Multiple inputs and outputs
(Number Number -- Number Number) {
    over over / swap %
} ::divmod fn

10 3 divmod   // => 3 1 (quotient remainder)

Function Bodies: The { } braces contain a TokenString that is parsed as the function body when the function is defined. See Section 5.5 for details on TokenStrings.

Related: See Section 10.2 for generic functions with type parameters.

5.3 Calling Functions

Functions are called by simply writing their name. The postfix notation means arguments must be on the stack before the function name:

// Define a function
(Number Number -- Number) { + } ::add fn

// Call it
3 4 add       // => 7

// Chain functions
5 square 2 * // => 50 (square 5, then multiply by 2)

Function Chaining: Since everything is postfix, functions naturally chain left-to-right:

10 square 2 / 5 +    // ((10²) / 2) + 5 = 55

5.4 Recursion

Functions can call themselves recursively:

(Number -- Number) {
    dup 1 <=
        { drop 1 }
        { dup 1 - factorial * }
    if
} ::factorial fn

5 factorial    // => 120

Stack Considerations: Recursive functions consume stack space. Deep recursion may cause stack overflow. Consider iterative alternatives for performance-critical code.

5.5 Token Strings

Token strings are lexed but unparsed code blocks enclosed in { }. They are parsed differently depending on which operator uses them.

Operators that parse TokenStrings:

  • fn - Parses as function body (code block)
  • trait - Parses as trait definition (method signatures)
  • impl - Parses as trait implementation (method definitions)
  • eval - Parses and executes as code block immediately
  • lambda - Parses as code block, pushes the block as a callable value
  • if - Parses both TokenStrings as code blocks (then/else branches)
  • while - Parses both TokenStrings as code blocks (condition/body)
  • for - Parses TokenString as code block (loop body)
  • match - Parses TokenString as pattern matching arms
  • map, filter, reduce, each - Parse TokenStrings as code blocks for array operations

Examples:

// Function body (parsed by fn)
(Number -- Number) { dup * } ::square fn

// Conditional branches (parsed by if)
x 0 > { "positive" print } { "negative" print } if

// Loop body (parsed by while)
{ dup 10 < } { dup print 1 + } while

5.6 Lambda Functions

The lambda operator converts a TokenString into a callable code block that can be stored and passed around:

{ dup * } lambda        // Creates a callable code block
::square_fn swap        // Store reference to the lambda

// Later use:
5 square_fn eval        // Calls the lambda: pushes 25

Use Cases:

  • Creating first-class functions
  • Passing code blocks as values
  • Dynamic dispatch
  • Higher-order operations

Example with arrays:

// Store a lambda and use it with map
{ 2 * } lambda ::double swap
[1 2 3 4] double map    // => [2 4 6 8]

Related: See Section 11.1 for the eval operator used to execute lambdas.


6. Control Flow

6.1 Conditionals

Syntax: condition { then-block } { else-block } if

The condition is evaluated first, then both code blocks are provided, followed by the if operator which chooses which block to execute.

Examples:

// if-then (else block is empty)
x 0 > { "positive" print } { } if

// if-then-else
x 0 > 
    { "positive" print } 
    { "non-positive" print } 
if

// Returning values
a b > 
    { a } 
    { b } 
if    // Pushes the maximum of a and b

// Nested conditionals
x 0 >
    {
        y 0 >
            { "both positive" print }
            { "x positive, y not" print }
        if
    }
    { "x not positive" print }
if

Important: The if operator parses both TokenStrings as code blocks. The condition must produce a boolean value (or truthy value) before the if operator.

6.2 While Loops

Syntax: { condition-block } { body-block } while

The while loop repeatedly evaluates the condition block and executes the body block as long as the condition is truthy.

Examples:

// Sum 1 to 10
0 1                              // sum counter
    { dup 10 <= }                // condition block
    {                            // body block
        over over +              // Add counter to sum
        swap 1 + swap            // Increment counter
    }
while
drop                             // Drop counter, leave sum

// Infinite loop with break
{ true } {
    // body
    condition { break } { } if
} while

Condition Evaluation: The condition block is re-evaluated before each iteration. It should leave a boolean (or truthy) value on the stack.

6.3 For Loops

Syntax: start end { body-with-counter } for

The for loop iterates from start to end (inclusive), pushing the loop counter onto the stack for each iteration before executing the body.

Examples:

// Print 1 to 10
1 10 { 
    // Stack has loop counter on top
    dup print
} for

// FizzBuzz
1 100 {
    dup fizzbuzz
} for

// Accumulation
0                    // accumulator
1 10 {
    +                // add counter to accumulator
} for
// Result: 55 (sum of 1 to 10)

Loop Counter: The loop counter is automatically pushed onto the stack before each iteration. Your body block should consume it or clean it up.

6.4 Loop Control

break       // Exit the current loop immediately
continue    // Skip to the next iteration of the current loop

Examples:

// Break example
1 100 {
    dup 50 ==
        { break }
        { dup print }
    if
} for    // Prints 1-49, stops at 50

// Continue example
1 10 {
    dup 2 % 0 ==
        { continue }
        { dup print }
    if
} for    // Prints only odd numbers: 1 3 5 7 9

6.5 Pattern Matching

Syntax: value { pattern => block ... } match

Pattern matching allows you to test a value against multiple patterns and execute the corresponding block.

Examples:

// Option matching
opt_value {
    Some(x) => { x print }
    None => { "Nothing" print }
} match

// Multiple patterns
status {
    Pending => { "Waiting" print }
    Active => { "Running" print }
    Complete => { "Done" print }
} match

// Result matching
result {
    Ok(val) => { val process }
    Err(e) => { e "Error: " swap concat print }
} match

Pattern Syntax: Patterns can match enum variants, union variants, or literal values. The matched value (if any) is bound and available in the corresponding block.


7. Data Structures

7.1 Structs

Structs define composite types with named fields.

Definition Syntax: (field_types -- ) { field_names: } ::name<type_params>? struct

Examples:

// Define Point struct - generic over coordinate types
(T T --) { x: y: } ::Point<T> struct

// Use with specific types
3.0 4.0 Point       // Creates Point with f64 fields
3 4 Point           // Creates Point with i64 fields

// More complex struct
(T U V --) { 
    width: 
    height: 
    depth: 
} ::Box3D<T U V> struct

10.0 20.0 30.0 Box3D

Field Access:

  • get: struct ::field get - Consumes struct and field identifier, returns field value
  • set: value ::field set - Consumes value and field identifier, returns modified struct

Examples:

point ::x get         // Get x field (consumes point and ::x)
15.0 ::x set          // Set x field to 15.0 (consumes value and ::x)

// Chaining with duplication
point dup ::x get 2 * over ::y get +     // (point.x * 2) + point.y

Note: Structs can be generic. See Section 10.3 for details on generic data structures.

7.2 Unions

Unions define tagged variants, where a value is one of several possible types.

Definition Syntax: (variant_types -- ) { variants } ::name<type_params>? union

Examples:

// Option type - generic over T
(T --) { 
    Some(T) 
    None 
} ::Option<T> union

// Result type - generic over T and E
(T E --) { 
    Ok(T) 
    Err(E) 
} ::Result<T E> union

// Create union values
42 Option::Some      // Creates Option::Some(42)
Option::None         // Creates Option::None
"success" Result::Ok // Creates Result::Ok("success")
"error" Result::Err  // Creates Result::Err("error")

Pattern Matching: Unions are typically used with pattern matching (Section 6.5) to handle different variants.

Note: Unions can be generic. See Section 10.3 for details on generic data structures.

7.3 Enums

Enums define a fixed set of named values with optional integer assignments.

Definition Syntax: { variants } ::name enum

Examples:

{ 
    Pending 1:   // Explicitly set to 1
    Active:      // Defaults to 2 (one plus the last)
    Complete 0:  // Explicitly set to 0
} ::Status enum

// Usage
Status::Pending     // Creates Status::Pending (value 1)
Status::Active      // Creates Status::Active (value 2)
Status::Complete    // Creates Status::Complete (value 0)

Automatic Values: If not specified, enum values start at 0 and increment by 1 for each subsequent variant.

7.4 Arrays

Arrays are homogeneous collections of values.

Array Literals:

[1 2 3 4 5]              // array of i64
[1.0 2.0 3.0]            // array of f64
[[1 2] [3 4]]            // 2D array

Basic Operations:

arr 2 at                 // ( array index -- element ) Access element at index
arr 1 3 slice            // ( array start end -- subarray ) Extract slice
arr length               // ( array -- length ) Get array length

Array Combinators:

These operations take TokenString arguments containing function bodies:

// Map - transform each element
[1 2 3 4] { 2 * } map        // => [2 4 6 8]

// Filter - keep elements matching predicate
[1 2 3 4 5] { 2 % 0 == } filter   // => [2 4]

// Reduce - fold with accumulator
[1 2 3 4] 0 { + } reduce     // => 10

// Each - apply to each element (side effects)
[[1 2] [3 4]] { sum print } each

Array Arithmetic:

[1 2 3] [4 5 6] +.      // Element-wise add: [5 7 9]
[1 2 3] [4 5 6] *.      // Element-wise multiply: [4 10 18]
[1 2 3] 2 *.            // Scalar multiply: [2 4 6]

Array Manipulation:

[1 2 3] [4 5 6] concat  // Concatenate: [1 2 3 4 5 6]
[1 2 3] reverse         // Reverse: [3 2 1]
[[1 2] [3 4]] transpose // Transpose: [[1 3] [2 4]]
[1 2 3 4] 2 window      // Sliding window: [[1 2] [2 3] [3 4]]

Implementation Details: Array operations implement various traits including ::ArrayOf<T>, ::Selectable<T>, ::Sliceable, and ::Sized. See Appendix B for complete trait definitions and Appendix A for the full array operation reference.


8. Type System

8.1 Types vs Traits

The language distinguishes between types (what things are) and traits (how things behave):

Types define the concrete structure and memory layout:

  • Point - A struct type with two fields
  • Rectangle - A struct type with width and height
  • i32 - A primitive integer type
  • Option<T> - A union type that may contain a value

Traits define behavioral contracts:

  • ::Addable - Types that support addition and subtraction
  • ::Drawable - Types that can be drawn
  • ::Stackable - Types that support stack operations

Key Distinction:

  • A value has a type (what it is structurally)
  • A value implements a trait (how it behaves)
  • Types are concrete; traits are interfaces
  • Functions can be generic over traits
  • Functions can specify types or traits in signatures
  • Every operator must be backed by a trait

Examples:

// Point is a type
(T T --) { x: y: } ::Point<T> struct

// Addable is a trait
{
    (Self Self -- Self) +:
    (Self Self -- Self) -:
} ::Addable trait

// Point implements Addable (Point now behaves additively)
::Addable {
    (Self Self -- Self) {
        over ::x get over ::x get +
        swap ::y get swap ::y get +
        Point
    } +:
    // ... subtract implementation ...
} ::Point impl

Related: See Section 9 for the complete trait system and Appendix B for all standard trait definitions.

8.2 Type Inference

The compiler infers types in most situations, minimizing the need for explicit type annotations.

When Type Inference Works:

42              // Inferred as i64 (default integer)
3.14            // Inferred as f64 (default float)
[1 2 3]         // Inferred as array of i64

// Function return type inferred from body
(Number -- Number) { dup * } ::square fn
5 square        // Compiler knows result is Number

When Annotations Are Needed:

42:i32          // Explicit annotation for 32-bit integer
3.14:f32        // Explicit annotation for 32-bit float

// Ambiguous generic contexts may need hints
parse           // May need type context to know what to parse to

Type Inference with Generics:

// Type parameter T is inferred from usage
(T -- T) { } ::identity fn

5 identity      // T inferred as i64
"hello" identity // T inferred as String

Related: See Section 10 for generic programming and type parameter inference.

8.3 Type Tuples

Type tuples represent stack effects and are used in function signatures to specify what a function consumes from and produces to the stack.

Syntax: (inputs -- outputs)

Examples:

(T T -- T)               // Two inputs of type T, one output of type T
(i32 f64 -- String)      // Takes i32 and f64, returns String
(-- bool)                // No inputs, returns bool
(Point --)               // Takes Point, no outputs
(---)                    // No inputs, no outputs (side effects only)

Variable Arguments with Iterable:

For operations that need variable numbers of arguments, use the Iterable trait:

(-- Size) depth:                           // Zero arguments, returns stack depth
(String Iterable<Stringifiable> --) printf: // String plus iterable of printable values
(Iterable<T> -- T) sum:                    // Iterable of values, returns sum

Examples:

"x=%d, y=%d" [x y] printf    // Format string with array of values
[1 2 3 4 5] sum              // Sum array of numbers
depth print                   // No arguments needed

This approach keeps the type system simple without special variadic syntax.

8.4 Type Composition

Types can contain other types, creating composite data structures:

Nested Structures:

// Point contains two T values
(T T --) { x: y: } ::Point<T> struct

// Line contains two Points
(Point<T> Point<T> --) { start: end: } ::Line<T> struct

Arrays of Types:

[1 2 3]                          // Array of i64
[[1 2] [3 4]]                    // Array of arrays
[Point Point Point]              // Array of Points

Generic Composition:

// Box contains a value of any type
(T --) { value: } ::Box<T> struct

// Option can contain any type (or nothing)
(T --) { Some(T) None } ::Option<T> union

// Nested generics
Option<Point<f64>>               // Option containing a Point of f64s

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.


10. Generic Programming

10.1 Type Parameters

Type parameters allow functions, structs, and traits to work with multiple types.

Generic Syntax: <T> where T is a type parameter

Examples:

// Generic struct
(T T --) { x: y: } ::Point<T> struct

// Generic union
(T --) { Some(T) None } ::Option<T> union

// Generic trait
{
    (Self T -- Self) append:
} ::Container<T> trait

Type Parameter Constraints:

When operations are performed on type parameters, they must be constrained by traits:

// Unconstrained - no operations on T
(T -- T) { } ::identity fn

// Constrained - T must support multiplication
(T:Multiplyable -- T) { dup * } ::square fn

Multiple Type Parameters:

(T E --) { Ok(T) Err(E) } ::Result<T E> union

10.2 Generic Functions

Generic functions work with multiple types by using trait constraints in their type tuples.

Syntax: (trait_constraints -- outputs) { body } ::name fn

Examples:

// Generic identity - works with any type (no operations, no constraint needed)
(T -- T) { } ::identity fn

// Requires Addable trait
(Addable Addable -- Addable) {
    +
} ::add_values fn

// Requires Number trait
(Number -- Number) {
    dup 0 > { } { 0 swap - } if
} ::abs fn

// Multiple constraints
(Number Number -- Number) {
    dup * swap dup * +  // a² + b²
} ::pythagorean fn

Type Inference: The compiler infers the actual type from usage:

5 identity          // T inferred as i64
"hello" identity    // T inferred as String
3 4 add_values      // Addable inferred as i64

10.3 Generic Data Structures

Structs and unions can be generic over type parameters:

Generic Structs:

// Point is generic over coordinate type
(T T --) { x: y: } ::Point<T> struct

// Use with different types
3.0 4.0 Point       // Point<f64>
3 4 Point           // Point<i64>

// Multiple type parameters
(T U --) { first: second: } ::Pair<T U> struct
5 "hello" Pair      // Pair<i64 String>

Generic Unions:

// Option is generic over contained type
(T --) { Some(T) None } ::Option<T> union

42 Option::Some     // Option<i64>::Some
"text" Option::Some // Option<String>::Some
Option::None        // Option<T>::None (T inferred from context)

// Result with two type parameters
(T E --) { Ok(T) Err(E) } ::Result<T E> union

Nested Generics:

// Array of Options
[Option::Some Option::None]           // Array of Option<T>

// Option of array
[1 2 3] Option::Some                  // Option<Array<i64>>

10.4 Generic Traits

Traits can be generic, allowing them to describe behavior parameterized over types.

Generic Trait Syntax:

// Container generic over element type
{
    (Self T -- Self) append:
    (Self -- T) pop:
} ::Container<T> trait

// Map generic over key and value types
{
    (Self K -- V) get:
    (Self K V -- Self) insert:
} ::Map<K V> trait

Generic Trait Inheritance:

When inheriting from generic traits, you must either:

  1. Make the inheriting trait similarly generic
  2. Specify concrete types for the generic parameters
// Inheriting trait is also generic
[ ::Container<T> ] ::Stack<T> inher
{
    (Self -- T) peek:
} ::Stack<T> trait

// Inheriting trait specifies concrete type
[ ::Container<i32> ] ::IntStack inher
{
    (Self -- i32) peek:
} ::IntStack trait

// Multiple generic inheritance
[ ::Selectable<T> ::Sized ::Sliceable ] ::ArrayOf<T> inher
{ } ::ArrayOf<T> trait

10.5 Type Parameter Enforcement

Current Behavior: Type parameters are currently suggestions when parsing code blocks. The compiler does not yet enforce that type parameters actually constrain how operators and functions act at parse time.

Example:

// Currently no error even without Multiplyable constraint
(T -- T) { dup * } ::square fn

// Should require constraint
(Multiplyable -- Multiplyable) { dup * } ::square fn

Future Enhancement: See Appendix F for planned type parameter enforcement at parse time.


11. Advanced Topics

11.1 Dynamic Code Evaluation

The eval operator executes code dynamically at runtime by parsing and executing a TokenString.

Syntax: { code } eval

Examples:

// Evaluate simple expression
"2 3 +" eval            // Pushes 5

// Build and execute code
"(Multiplyable -- Multiplyable) { dup * } ::square fn" eval
5 square                // 25

// Dynamic dispatch
operation_name " get" concat eval

Use Cases:

  • Building code at runtime
  • Dynamic dispatch based on runtime values
  • Implementing interpreters or REPLs
  • Meta-programming

Warnings:

  • Eval introduces runtime overhead (parsing)
  • Type safety is reduced (types checked at eval time, not compile time)
  • Security risk if evaluating untrusted code
  • Use sparingly and prefer static alternatives when possible

11.2 Identifier Literals

Identifier literals use the :: prefix to push an identifier as a value rather than executing it.

Syntax: ::name

Context-Dependent Rules:

In function bodies and eval: :: is required for identifier literals

::Point                 // Pushes identifier "Point"
::Addable              // Pushes identifier "Addable"

In trait definitions: :: is not allowed (identifiers are method names)

{
    (Self -- ) draw:    // "draw:" is a method name, not a literal
} ::Drawable trait

In trait implementations: :: is not allowed (identifiers are method names)

::Drawable {
    (Self -- ) { ... } draw:  // "draw:" is a method name
} ::Rectangle impl

Use Cases:

  • Defining structs: (T T --) { x: y: } ::Point<T> struct
  • Defining traits: { ... } ::Drawable trait
  • Field access: point ::x get
  • Dynamic trait operations
  • Meta-programming

11.3 Standard Library

The standard library provides I/O, string operations, type conversions, and utility functions. All standard library functions are automatically in scope (no imports needed in current version).

I/O Operations:

"Hello" print           // Print string to stdout
"Enter name: " input    // Read line from stdin
"file.txt" read         // Read file contents as string
"data" "file.txt" write // Write string to file

String Operations:

"hello" " world" concat     // Concatenate strings
"hello" length              // Get string length
"hello" 1 3 substr          // Extract substring
"a,b,c" "," split           // Split by delimiter
["a" "b"] "," join          // Join with delimiter

Type Conversion:

42 to_f64               // Convert i32 to f64
3.14 to_i32             // Convert f64 to i32 (truncates)
"123" parse             // Parse string to inferred type
42 to_str               // Convert to string

Array Operations:

  • Element access: at, slice
  • Information: length, shape
  • Combinators: map, filter, reduce, each
  • Manipulation: concat, reverse, transpose, window

Complete Reference: See Appendix A for the full standard library reference with all functions, signatures, and examples.


Appendix A: Standard Library

This appendix provides a complete alphabetical reference of all standard library functions and operations.

Standard Library Categories

Array Operations: at, concat, each, filter, length, map, reduce, reverse, shape, slice, transpose, window

I/O Operations: input, print, read, write

String Operations: concat, join, length, split, substr

Type Conversion: parse, to_i8, to_i16, to_i32, to_i64, to_u8, to_u16, to_u32, to_u64, to_f32, to_f64, to_str

Utility Operations: eval, lambda

Alphabetical Reference

at

Signature: (Selectable<T> Size -- T)
Trait: Selectable
Description: Access element at the given index.
Example:

[10 20 30] 1 at  // Returns 20

See Also: slice, length

concat

Signature: (Concatenable Concatenable -- Concatenable)
Trait: Concatenable
Description: Concatenate two containers or strings.
Example:

[1 2 3] [4 5 6] concat  // Returns [1 2 3 4 5 6]
"hello" " world" concat // Returns "hello world"

See Also: join, split

depth

Signature: (-- Size)
Trait: Stackable
Description: Push current stack depth onto the stack.
Example:

1 2 3 depth  // Returns 1 2 3 3

See Also: pick, roll

drop

Signature: (Self --)
Trait: Stackable
Description: Remove and discard the top item from the stack.
Example:

5 10 drop  // Returns 5

See Also: dup, swap

dup

Signature: (Self -- Self Self)
Trait: Stackable
Description: Duplicate the top item on the stack.
Example:

5 dup  // Returns 5 5

See Also: drop, over

each

Signature: (ArrayOf<T> TokenString --)
Description: Apply function to each element (side effects).
Example:

[1 2 3] { print } each  // Prints 1, 2, 3

See Also: map, filter

eval

Signature: (TokenString --)
Trait: Implementable
Description: Parse and execute TokenString as code.
Example:

"2 3 +" eval  // Returns 5

See Also: lambda

filter

Signature: (ArrayOf<T> TokenString -- ArrayOf<T>)
Description: Keep only elements matching predicate.
Example:

[1 2 3 4 5] { 2 % 0 == } filter  // Returns [2 4]

See Also: map, reduce

input

Signature: (String -- String)
Description: Print prompt and read line from stdin.
Example:

"Enter name: " input  // Prompts and returns user input

See Also: print, read

join

Signature: (ArrayOf<String> String -- String)
Description: Join array of strings with delimiter.
Example:

["a" "b" "c"] "," join  // Returns "a,b,c"

See Also: split, concat

lambda

Signature: (TokenString -- Callable)
Trait: Implementable
Description: Convert TokenString to callable code block.
Example:

{ dup * } lambda ::square swap
5 square eval  // Returns 25

See Also: eval

length

Signature: (Sized -- i64)
Trait: Sized
Description: Get the number of elements in a container.
Example:

[1 2 3 4 5] length  // Returns 5
"hello" length      // Returns 5

See Also: at, slice

map

Signature: (ArrayOf<T> TokenString -- ArrayOf<U>)
Description: Transform each element with function.
Example:

[1 2 3 4] { 2 * } map  // Returns [2 4 6 8]

See Also: filter, reduce, each

over

Signature: (Self Self -- Self Self Self)
Trait: Stackable
Description: Copy the second item to the top of the stack.
Example:

5 10 over  // Returns 5 10 5

See Also: dup, swap, rot

parse

Signature: (String -- Parseable)
Trait: Parseable
Description: Parse string to value of inferred type.
Example:

"123" parse  // Returns 123 (as appropriate numeric type)

See Also: to_str

pick

Signature: (Size -- Self)
Trait: Stackable
Description: Copy nth item to top (0 = top, 1 = second, etc.).
Example:

1 2 3 4 2 pick  // Returns 1 2 3 4 2

See Also: roll, depth

print

Signature: (Stringifiable --)
Description: Print value to stdout.
Example:

"Hello" print  // Prints: Hello
42 print       // Prints: 42

See Also: input, to_str

read

Signature: (String -- String)
Description: Read file contents as string.
Example:

"file.txt" read  // Returns file contents

See Also: write

reduce

Signature: (ArrayOf<T> T TokenString -- T)
Description: Fold array with accumulator function.
Example:

[1 2 3 4] 0 { + } reduce  // Returns 10

See Also: map, filter

reverse

Signature: (ArrayOf<T> -- ArrayOf<T>)
Description: Reverse order of array elements.
Example:

[1 2 3] reverse  // Returns [3 2 1]

See Also: transpose

roll

Signature: (Size Size --)
Trait: Stackable
Description: Rotate n items, times times.
Example:

1 2 3 4 3 1 roll  // Rotates top 3 once: 1 3 4 2

See Also: rot, pick

rot

Signature: (Self Self Self -- Self Self Self)
Trait: Stackable
Description: Rotate the top three items.
Example:

1 2 3 rot  // Returns 2 3 1

See Also: swap, roll

slice

Signature: (Sliceable Size Size -- Sliceable)
Trait: Sliceable
Description: Extract elements from start to end index.
Example:

[10 20 30 40] 1 3 slice  // Returns [20 30]

See Also: at, length

split

Signature: (String String -- ArrayOf<String>)
Trait: String
Description: Split string by delimiter.
Example:

"a,b,c" "," split  // Returns ["a" "b" "c"]

See Also: join, substr

substr

Signature: (String Size Size -- String)
Trait: String
Description: Extract substring from start to end index.
Example:

"hello" 1 3 substr  // Returns "el"

See Also: slice, split

swap

Signature: (Self Self -- Self Self)
Trait: Stackable
Description: Swap the top two items on the stack.
Example:

5 10 swap  // Returns 10 5

See Also: dup, rot

to_f32, to_f64

Signature: (Convertible -- f32/f64)
Trait: Convertible
Description: Convert value to 32-bit or 64-bit float.
Example:

42 to_f64  // Returns 42.0

See Also: to_i32, to_str

to_i8, to_i16, to_i32, to_i64

Signature: (Convertible -- i8/i16/i32/i64)
Trait: Convertible
Description: Convert value to signed integer type.
Example:

3.14 to_i32  // Returns 3 (truncates)

See Also: to_u32, to_f64

to_str

Signature: (Stringifiable -- String)
Trait: Stringifiable
Description: Convert value to string representation.
Example:

42 to_str  // Returns "42"

See Also: parse, print

to_u8, to_u16, to_u32, to_u64

Signature: (Convertible -- u8/u16/u32/u64)
Trait: Convertible
Description: Convert value to unsigned integer type.
Example:

42 to_u32  // Returns 42 (as u32)

See Also: to_i32, to_f64

transpose

Signature: (ArrayOf<ArrayOf<T>> -- ArrayOf<ArrayOf<T>>)
Description: Transpose a 2D array (swap rows and columns).
Example:

[[1 2] [3 4]] transpose  // Returns [[1 3] [2 4]]

See Also: reverse

window

Signature: (ArrayOf<T> Size -- ArrayOf<ArrayOf<T>>)
Description: Create sliding windows of given size.
Example:

[1 2 3 4] 2 window  // Returns [[1 2] [2 3] [3 4]]

See Also: slice

write

Signature: (String String --)
Description: Write string to file.
Example:

"data" "file.txt" write  // Writes "data" to file.txt

See Also: read


Appendix B: Complete Trait Reference

This appendix contains all built-in trait definitions with complete documentation, organized alphabetically.

Trait List

  • Addable
  • ArrayOf
  • Bitwise
  • Comparable
  • Concatenable
  • Convertible
  • Equatable
  • Exponentiable
  • Identifier
  • Implementable
  • Iterable
  • Logarithmic
  • Logical
  • Multiplyable
  • Number
  • Orderable
  • Parseable
  • Selectable
  • Size
  • Sized
  • Sliceable
  • Stackable
  • String
  • Stringifiable

Addable

Generic Parameters: None
Inherits: None

Definition:

{
    (Self Self -- Self) +:
    (Self Self -- Self) -:
} ::Addable trait

Methods:

+:

Signature: (Self Self -- Self)
Description: Add two values together.
Example: 3 4 + // => 7

-:

Signature: (Self Self -- Self)
Description: Subtract second value from first.
Example: 10 3 - // => 7

Standard Implementations: All numeric types (i8, i16, i32, i64, u8, u16, u32, u64, f32, f64)

Related Traits: Multiplyable, Number

See Also: Section 4.2 (Arithmetic Operators)

ArrayOf

Generic Parameters: T (element type)
Inherits: Sized, Selectable, Sliceable

Definition:

[ ::Sized ::Selectable<T> ::Sliceable ] ::ArrayOf<T> inher
{ } ::ArrayOf<T> trait

Description: Composite trait for arrays, inheriting all container operations.

Standard Implementations: Array types

Related Traits: Sized, Selectable, Sliceable, Iterable

See Also: Section 7.4 (Arrays)

Bitwise

Generic Parameters: None
Inherits: None

Definition:

{
    (Self Self -- Self) bitand:
    (Self Self -- Self) bitor:
    (Self Self -- Self) bitxor:
    (Self -- Self) bitnot:
    (Self Size -- Self) shl:
    (Self Size -- Self) shr:
} ::Bitwise trait

Methods:

bitand:

Signature: (Self Self -- Self)
Description: Bitwise AND of two values.
Example: 0xFF 0x0F bitand // => 0x0F

bitor:

Signature: (Self Self -- Self)
Description: Bitwise OR of two values.
Example: 0xF0 0x0F bitor // => 0xFF

bitxor:

Signature: (Self Self -- Self)
Description: Bitwise XOR of two values.
Example: 0xFF 0x0F bitxor // => 0xF0

bitnot:

Signature: (Self -- Self)
Description: Bitwise NOT (complement) of value.
Example: 0xFF bitnot // => (inverted bits)

shl:

Signature: (Self Size -- Self)
Description: Shift bits left by n positions.
Example: 4 2 shl // => 16

shr:

Signature: (Self Size -- Self)
Description: Shift bits right by n positions.
Example: 16 2 shr // => 4

Standard Implementations: Integer types (i8, i16, i32, i64, u8, u16, u32, u64)

Related Traits: None

See Also: Section 4.5 (Bitwise Operators)

Comparable

Generic Parameters: None
Inherits: Orderable, Equatable

Definition:

[ ::Orderable ::Equatable ] ::Comparable inher
{ } ::Comparable trait

Description: Composite trait combining ordering and equality comparisons.

Standard Implementations: All numeric types, strings, characters

Related Traits: Orderable, Equatable, Size, Number

See Also: Section 4.3 (Comparison Operators)

Concatenable

Generic Parameters: None
Inherits: None

Definition:

{
    (Self Self -- Self) concat:
} ::Concatenable trait

Methods:

concat:

Signature: (Self Self -- Self)
Description: Join two containers or strings together.
Example: "hello" " world" concat // => "hello world"

Standard Implementations: Arrays, strings

Related Traits: String, ArrayOf

See Also: Section 7.4 (Arrays), Appendix A (concat)

Convertible

Generic Parameters: None
Inherits: None

Definition:

{
    (Self -- i8) to_i8:
    (Self -- i16) to_i16:
    (Self -- i32) to_i32:
    (Self -- i64) to_i64:
    (Self -- u8) to_u8:
    (Self -- u16) to_u16:
    (Self -- u32) to_u32:
    (Self -- u64) to_u64:
    (Self -- f32) to_f32:
    (Self -- f64) to_f64:
} ::Convertible trait

Methods: Provides explicit type conversion methods to all numeric types.

Standard Implementations: All numeric types

Related Traits: Stringifiable, Parseable, Size

See Also: Section 11.3 (Type Conversion)

Equatable

Generic Parameters: None
Inherits: None

Definition:

{
    (Self Self -- bool) ==:
    (Self Self -- bool) !=:
} ::Equatable trait

Methods:

==:

Signature: (Self Self -- bool)
Description: Test if two values are equal.
Example: 5 5 == // => true

!=:

Signature: (Self Self -- bool)
Description: Test if two values are not equal.
Example: 5 3 != // => true

Standard Implementations: All types

Related Traits: Orderable, Comparable

See Also: Section 4.3 (Comparison Operators)

Exponentiable

Generic Parameters: None
Inherits: None

Definition:

{
    (Self Self -- Self) ^:
} ::Exponentiable trait

Methods:

^:

Signature: (Self Self -- Self)
Description: Raise first value to the power of the second.
Example: 2 8 ^ // => 256

Standard Implementations: Numeric types

Related Traits: Addable, Multiplyable, Number

See Also: Section 4.2 (Arithmetic Operators)

Identifier

Generic Parameters: None
Inherits: None

Definition:

{ } ::Identifier trait

Description: Marker trait for identifier types.

Standard Implementations: Identifier literals

Related Traits: Implementable

See Also: Section 11.2 (Identifier Literals)

Implementable

Generic Parameters: None
Inherits: None

Definition:

{
    (TokenString Identifier --) trait:
    (Identifier TokenString Identifier --) impl:
    (ArrayOf<Identifier> Identifier --) inher:
} ::Implementable trait

Methods:

trait:

Signature: (TokenString Identifier --)
Description: Define a new trait.
Example: { (Self -- ) draw: } ::Drawable trait

impl:

Signature: (Identifier TokenString Identifier --)
Description: Implement a trait for a type.
Example: ::Drawable { ... } ::Rectangle impl

inher:

Signature: (ArrayOf<Identifier> Identifier --)
Description: Declare trait inheritance.
Example: [ ::Orderable ::Equatable ] ::Comparable inher

Standard Implementations: Language-level operators

Related Traits: Identifier

See Also: Section 9 (Trait System)

Iterable

Generic Parameters: T (element type)
Inherits: None

Definition:

{
    (Self -- Self Option<T>) next:
} ::Iterable<T> trait

Methods:

next:

Signature: (Self -- Self Option<T>)
Description: Get next item from iterator.
Example: Iterator protocol for collections

Standard Implementations: Arrays, ranges, iterators

Related Traits: ArrayOf, Selectable

See Also: Section 8.3 (Type Tuples - Variable Arguments)

Logarithmic

Generic Parameters: None
Inherits: None

Definition:

{
    (Self Self -- Self) logb:
    (Self -- Self) log:
    (Self -- Self) ln:
} ::Logarithmic trait

Methods:

logb:

Signature: (Self Self -- Self)
Description: Logarithm with custom base.
Example: 8 2 logb // => 3.0

log:

Signature: (Self -- Self)
Description: Logarithm base 10.
Example: 100 log // => 2.0

ln:

Signature: (Self -- Self)
Description: Natural logarithm (base e).
Example: 2.718 ln // => 1.0

Standard Implementations: Floating point types

Related Traits: Exponentiable, Number

See Also: Section 4.2 (Arithmetic Operators)

Logical

Generic Parameters: None
Inherits: None

Definition:

{
    (Self -- bool) truthy:
    (Self Self -- Self) and:
    (Self Self -- Self) or:
    (Self -- Self) not:
} ::Logical trait

Methods:

truthy:

Signature: (Self -- bool)
Description: Convert to boolean (truthiness check).
Example: 5 truthy // => true, 0 truthy // => false

and:

Signature: (Self Self -- Self)
Description: Logical AND - returns first if falsy, else second.
Example: true false and // => false

or:

Signature: (Self Self -- Self)
Description: Logical OR - returns first if truthy, else second.
Example: true false or // => true

not:

Signature: (Self -- Self)
Description: Logical NOT - inverts truthiness.
Example: false not // => true

Standard Implementations: bool, numbers, Option, Result

Related Traits: None

See Also: Section 4.4 (Logical Operators)

Multiplyable

Generic Parameters: None
Inherits: None

Definition:

{
    (Self Self -- Self) *:
    (Self Self -- Self) /:
    (Self Self -- Self) %:
} ::Multiplyable trait

Methods:

*:

Signature: (Self Self -- Self)
Description: Multiply two values.
Example: 5 6 * // => 30

/:

Signature: (Self Self -- Self)
Description: Divide first value by second.
Example: 20 4 / // => 5

%:

Signature: (Self Self -- Self)
Description: Remainder after division (modulo).
Example: 17 5 % // => 2

Standard Implementations: All numeric types

Related Traits: Addable, Exponentiable, Number

See Also: Section 4.2 (Arithmetic Operators)

Number

Generic Parameters: None
Inherits: Addable, Multiplyable, Exponentiable, Comparable, Logarithmic

Definition:

[ ::Addable ::Multiplyable ::Exponentiable ::Comparable ::Logarithmic ] ::Number inher
{ } ::Number trait

Description: Composite trait representing the full suite of numeric operations.

Standard Implementations: All numeric types (i8, i16, i32, i64, u8, u16, u32, u64, f32, f64)

Related Traits: Addable, Multiplyable, Exponentiable, Comparable, Logarithmic

See Also: Section 4.2 (Arithmetic Operators)

Orderable

Generic Parameters: None
Inherits: None

Definition:

{
    (Self Self -- bool) >:
    (Self Self -- bool) >=:
    (Self Self -- bool) <:
    (Self Self -- bool) <=:
} ::Orderable trait

Methods:

>:

Signature: (Self Self -- bool)
Description: True if first value is greater than second.
Example: 5 3 > // => true

>=:

Signature: (Self Self -- bool)
Description: True if first value is greater than or equal to second.
Example: 5 5 >= // => true

<:

Signature: (Self Self -- bool)
Description: True if first value is less than second.
Example: 3 5 < // => true

<=:

Signature: (Self Self -- bool)
Description: True if first value is less than or equal to second.
Example: 5 5 <= // => true

Standard Implementations: All numeric types, strings, characters

Related Traits: Equatable, Comparable

See Also: Section 4.3 (Comparison Operators)

Parseable

Generic Parameters: None
Inherits: None

Definition:

{
    (String -- Self) parse:
} ::Parseable trait

Methods:

parse:

Signature: (String -- Self)
Description: Parse string to value of this type.
Example: "123" parse // => 123

Standard Implementations: All numeric types, bool

Related Traits: Stringifiable, Convertible

See Also: Appendix A (parse)

Selectable

Generic Parameters: T (element type)
Inherits: None

Definition:

{
    (Self Size -- T) at:
} ::Selectable<T> trait

Methods:

at:

Signature: (Self Size -- T)
Description: Access element at given index.
Example: [10 20 30] 1 at // => 20

Standard Implementations: Arrays, strings

Related Traits: ArrayOf, Sized, Sliceable

See Also: Section 7.4 (Arrays)

Size

Generic Parameters: None
Inherits: Addable, Comparable, Convertible

Definition:

[ ::Addable ::Comparable ::Convertible<i64> ] ::Size inher
{ } ::Size trait

Description: Represents types suitable for indexing and sizing operations.

Standard Implementations: All integer types (i8, i16, i32, i64, u8, u16, u32, u64)

Related Traits: Addable, Comparable, Convertible

See Also: Section 4.1 (Stack Operations - pick, roll)

Sized

Generic Parameters: None
Inherits: None

Definition:

{
    (Self -- i64) length:
} ::Sized trait

Methods:

length:

Signature: (Self -- i64)
Description: Get the number of elements in a container.
Example: [1 2 3 4 5] length // => 5

Standard Implementations: Arrays, strings

Related Traits: ArrayOf, Selectable, Sliceable

See Also: Section 7.4 (Arrays)

Sliceable

Generic Parameters: None
Inherits: None

Definition:

{
    (Self Size Size -- Self) slice:
} ::Sliceable trait

Methods:

slice:

Signature: (Self Size Size -- Self)
Description: Extract elements from start to end index.
Example: [10 20 30 40] 1 3 slice // => [20 30]

Standard Implementations: Arrays, strings

Related Traits: ArrayOf, Sized, Selectable

See Also: Section 7.4 (Arrays)

Stackable

Generic Parameters: None
Inherits: None

Definition:

{
    (Self -- Self Self) dup:
    (Self -- ) drop:
    (Self Self -- Self Self) swap:
    (Self Self -- Self Self Self) over:
    (Self Self Self -- Self Self Self) rot:
    (Size -- Self) pick:
    (Size Size -- ) roll:
    (-- Size) depth:
} ::Stackable trait

Methods:

dup:

Signature: (Self -- Self Self)
Description: Duplicate the top item on the stack.
Example: 5 dup // => 5 5

drop:

Signature: (Self -- )
Description: Remove and discard the top item.
Example: 5 10 drop // => 5

swap:

Signature: (Self Self -- Self Self)
Description: Swap the top two items.
Example: 5 10 swap // => 10 5

over:

Signature: (Self Self -- Self Self Self)
Description: Copy the second item to the top.
Example: 5 10 over // => 5 10 5

rot:

Signature: (Self Self Self -- Self Self Self)
Description: Rotate the top three items.
Example: 1 2 3 rot // => 2 3 1

pick:

Signature: (Size -- Self)
Description: Copy nth item to top (0 = top).
Example: 1 2 3 4 2 pick // => 1 2 3 4 2

roll:

Signature: (Size Size -- )
Description: Rotate n items, times times.
Example: 1 2 3 4 3 1 roll // => 1 3 4 2

depth:

Signature: (-- Size)
Description: Push current stack depth.
Example: 1 2 3 depth // => 1 2 3 3

Standard Implementations: All primitive types

Related Traits: None

See Also: Section 4.1 (Stack Operations)

String

Generic Parameters: None
Inherits: Concatenable

Definition:

[ ::Concatenable ] ::String inher
{
    (Self Size Size -- Self) substr:
    (Self Self -- ArrayOf<Self>) split:
} ::String trait

Methods:

substr:

Signature: (Self Size Size -- Self)
Description: Extract substring from start to end index.
Example: "hello" 1 3 substr // => "el"

split:

Signature: (Self Self -- ArrayOf<Self>)
Description: Split string by delimiter.
Example: "a,b,c" "," split // => ["a" "b" "c"]

Standard Implementations: String type

Related Traits: Concatenable, Sized, Sliceable

See Also: Section 11.3 (String Operations)

Stringifiable

Generic Parameters: None
Inherits: None

Definition:

{
    (Self -- String) to_str:
} ::Stringifiable trait

Methods:

to_str:

Signature: (Self -- String)
Description: Convert value to string representation.
Example: 42 to_str // => "42"

Standard Implementations: All types

Related Traits: Parseable, Convertible

See Also: Section 11.3 (Type Conversion)


Appendix C: Complete Operator Reference

This appendix provides a complete alphabetical reference of all operators in the language.

Operator List

!=, %, & (bitand), *, +, -, /, <, <=, ==, >, >=, ^, | (bitor), and, at, bitand, bitnot, bitor, bitxor, break, concat, continue, depth, drop, dup, each, enum, eval, filter, fn, for, get, if, impl, inher, lambda, length, ln, log, logb, map, match, not, or, over, pick, reduce, reverse, roll, rot, set, shl, shr, slice, struct, substr, swap, trait, transpose, union, while, window

Alphabetical Operator Reference

!=

Operator Type: Comparison
Signature: (Equatable Equatable -- bool)
Trait: Equatable
Description: Test if two values are not equal.
Example: 5 3 != // => true
See Also: ==, <, >
Section: 4.3 (Comparison Operators)

%

Operator Type: Arithmetic
Signature: (Multiplyable Multiplyable -- Multiplyable)
Trait: Multiplyable
Description: Remainder after division (modulo).
Example: 17 5 % // => 2
See Also: /, *
Section: 4.2 (Arithmetic Operators)

*

Operator Type: Arithmetic
Signature: (Multiplyable Multiplyable -- Multiplyable)
Trait: Multiplyable
Description: Multiply two values.
Example: 5 6 * // => 30
See Also: /, +, -
Section: 4.2 (Arithmetic Operators)

+

Operator Type: Arithmetic
Signature: (Addable Addable -- Addable)
Trait: Addable
Description: Add two values.
Example: 3 4 + // => 7
See Also: -, *, /
Section: 4.2 (Arithmetic Operators)

-

Operator Type: Arithmetic
Signature: (Addable Addable -- Addable)
Trait: Addable
Description: Subtract second value from first.
Example: 10 3 - // => 7
See Also: +, *, /
Section: 4.2 (Arithmetic Operators)

/

Operator Type: Arithmetic
Signature: (Multiplyable Multiplyable -- Multiplyable)
Trait: Multiplyable
Description: Divide first value by second.
Example: 20 4 / // => 5
See Also: *, %, +
Section: 4.2 (Arithmetic Operators)

<

Operator Type: Comparison
Signature: (Orderable Orderable -- bool)
Trait: Orderable
Description: True if first value is less than second.
Example: 3 5 < // => true
See Also: <=, >, >=
Section: 4.3 (Comparison Operators)

<=

Operator Type: Comparison
Signature: (Orderable Orderable -- bool)
Trait: Orderable
Description: True if first value is less than or equal to second.
Example: 5 5 <= // => true
See Also: <, >, >=
Section: 4.3 (Comparison Operators)

==

Operator Type: Comparison
Signature: (Equatable Equatable -- bool)
Trait: Equatable
Description: Test if two values are equal.
Example: 5 5 == // => true
See Also: !=, <, >
Section: 4.3 (Comparison Operators)

>

Operator Type: Comparison
Signature: (Orderable Orderable -- bool)
Trait: Orderable
Description: True if first value is greater than second.
Example: 5 3 > // => true
See Also: >=, <, <=
Section: 4.3 (Comparison Operators)

>=

Operator Type: Comparison
Signature: (Orderable Orderable -- bool)
Trait: Orderable
Description: True if first value is greater than or equal to second.
Example: 5 5 >= // => true
See Also: >, <, <=
Section: 4.3 (Comparison Operators)

^

Operator Type: Arithmetic
Signature: (Exponentiable Exponentiable -- Exponentiable)
Trait: Exponentiable
Description: Raise first value to power of second (exponentiation).
Example: 2 8 ^ // => 256
See Also: log, ln, logb
Section: 4.2 (Arithmetic Operators)

and

Operator Type: Logical
Signature: (Logical Logical -- Logical)
Trait: Logical
Description: Logical AND - returns first if falsy, else second.
Example: true false and // => false
See Also: or, not
Section: 4.4 (Logical Operators)

at

Operator Type: Container Access
Signature: (Selectable<T> Size -- T)
Trait: Selectable
Description: Access element at given index.
Example: [10 20 30] 1 at // => 20
See Also: slice, length
Section: 7.4 (Arrays)

bitand

Operator Type: Bitwise
Signature: (Bitwise Bitwise -- Bitwise)
Trait: Bitwise
Description: Bitwise AND of two values.
Example: 0xFF 0x0F bitand // => 0x0F
See Also: bitor, bitxor, bitnot
Section: 4.5 (Bitwise Operators)

bitnot

Operator Type: Bitwise
Signature: (Bitwise -- Bitwise)
Trait: Bitwise
Description: Bitwise NOT (complement) of value.
Example: 0xFF bitnot // => (inverted bits)
See Also: bitand, bitor, bitxor
Section: 4.5 (Bitwise Operators)

bitor

Operator Type: Bitwise
Signature: (Bitwise Bitwise -- Bitwise)
Trait: Bitwise
Description: Bitwise OR of two values.
Example: 0xF0 0x0F bitor // => 0xFF
See Also: bitand, bitxor, bitnot
Section: 4.5 (Bitwise Operators)

bitxor

Operator Type: Bitwise
Signature: (Bitwise Bitwise -- Bitwise)
Trait: Bitwise
Description: Bitwise XOR of two values.
Example: 0xFF 0x0F bitxor // => 0xF0
See Also: bitand, bitor, bitnot
Section: 4.5 (Bitwise Operators)

break

Operator Type: Control Flow
Signature: (--)
Description: Exit the current loop immediately.
Example: { true } { condition { break } { } if } while
See Also: continue, while, for
Section: 6.4 (Loop Control)

concat

Operator Type: Container
Signature: (Concatenable Concatenable -- Concatenable)
Trait: Concatenable
Description: Concatenate two containers or strings.
Example: [1 2 3] [4 5 6] concat // => [1 2 3 4 5 6]
See Also: slice, reverse
Section: 7.4 (Arrays)

continue

Operator Type: Control Flow
Signature: (--)
Description: Skip to the next iteration of the current loop.
Example: 1 10 { dup 2 % 0 == { continue } { print } if } for
See Also: break, while, for
Section: 6.4 (Loop Control)

depth

Operator Type: Stack Manipulation
Signature: (-- Size)
Trait: Stackable
Description: Push current stack depth onto the stack.
Example: 1 2 3 depth // => 1 2 3 3
See Also: pick, roll
Section: 4.1 (Stack Operations)

drop

Operator Type: Stack Manipulation
Signature: (Self --)
Trait: Stackable
Description: Remove and discard the top item from the stack.
Example: 5 10 drop // => 5
See Also: dup, swap
Section: 4.1 (Stack Operations)

dup

Operator Type: Stack Manipulation
Signature: (Self -- Self Self)
Trait: Stackable
Description: Duplicate the top item on the stack.
Example: 5 dup // => 5 5
See Also: drop, over
Section: 4.1 (Stack Operations)

each

Operator Type: Array Combinator
Signature: (ArrayOf<T> TokenString --)
Description: Apply function to each element (side effects).
Example: [1 2 3] { print } each
See Also: map, filter, reduce
Section: 7.4 (Arrays)

enum

Operator Type: Definition
Signature: (TokenString Identifier --)
Trait: Implementable
Description: Define an enumeration type.
Example: { Pending: Active: Complete: } ::Status enum
See Also: struct, union, trait
Section: 7.3 (Enums)

eval

Operator Type: Meta
Signature: (TokenString --)
Trait: Implementable
Description: Parse and execute TokenString as code.
Example: "2 3 +" eval // => 5
See Also: lambda
Section: 11.1 (Dynamic Code Evaluation)

filter

Operator Type: Array Combinator
Signature: (ArrayOf<T> TokenString -- ArrayOf<T>)
Description: Keep only elements matching predicate.
Example: [1 2 3 4 5] { 2 % 0 == } filter // => [2 4]
See Also: map, reduce, each
Section: 7.4 (Arrays)

fn

Operator Type: Definition
Signature: (TypeTuple TokenString Identifier --)
Trait: Implementable
Description: Define a function.
Example: (Number -- Number) { dup * } ::square fn
See Also: lambda, trait, impl
Section: 5.2 (Defining Functions)

for

Operator Type: Control Flow
Signature: (Size Size TokenString --)
Description: Loop from start to end, pushing counter each iteration.
Example: 1 10 { dup print } for
See Also: while, break, continue
Section: 6.3 (For Loops)

get

Operator Type: Struct Access
Signature: (Struct Identifier -- FieldValue)
Description: Get field value from struct (consumes struct and field identifier).
Example: point ::x get
See Also: set
Section: 7.1 (Structs)

if

Operator Type: Control Flow
Signature: (bool TokenString TokenString --)
Description: Conditional execution - execute first block if true, second if false.
Example: x 0 > { "positive" print } { "negative" print } if
See Also: match, while
Section: 6.1 (Conditionals)

impl

Operator Type: Definition
Signature: (Identifier TokenString Identifier --)
Trait: Implementable
Description: Implement a trait for a type.
Example: ::Addable { ... } ::Point impl
See Also: trait, inher
Section: 9.3 (Implementing Traits)

inher

Operator Type: Definition
Signature: (ArrayOf<Identifier> Identifier --)
Trait: Implementable
Description: Declare trait inheritance.
Example: [ ::Orderable ::Equatable ] ::Comparable inher
See Also: trait, impl
Section: 9.4 (Trait Inheritance)

lambda

Operator Type: Meta
Signature: (TokenString -- Callable)
Trait: Implementable
Description: Convert TokenString to callable code block.
Example: { dup * } lambda ::square swap
See Also: eval, fn
Section: 5.6 (Lambda Functions)

length

Operator Type: Container
Signature: (Sized -- i64)
Trait: Sized
Description: Get the number of elements in a container.
Example: [1 2 3 4 5] length // => 5
See Also: at, slice
Section: 7.4 (Arrays)

ln

Operator Type: Arithmetic
Signature: (Logarithmic -- Logarithmic)
Trait: Logarithmic
Description: Natural logarithm (base e).
Example: 2.718 ln // => 1.0
See Also: log, logb, ^
Section: 4.2 (Arithmetic Operators)

log

Operator Type: Arithmetic
Signature: (Logarithmic -- Logarithmic)
Trait: Logarithmic
Description: Logarithm base 10.
Example: 100 log // => 2.0
See Also: ln, logb, ^
Section: 4.2 (Arithmetic Operators)

logb

Operator Type: Arithmetic
Signature: (Logarithmic Logarithmic -- Logarithmic)
Trait: Logarithmic
Description: Logarithm with custom base.
Example: 8 2 logb // => 3.0
See Also: log, ln, ^
Section: 4.2 (Arithmetic Operators)

map

Operator Type: Array Combinator
Signature: (ArrayOf<T> TokenString -- ArrayOf<U>)
Description: Transform each element with function.
Example: [1 2 3 4] { 2 * } map // => [2 4 6 8]
See Also: filter, reduce, each
Section: 7.4 (Arrays)

match

Operator Type: Control Flow
Signature: (Value TokenString --)
Description: Pattern match value against multiple patterns.
Example: opt { Some(x) => { x print } None => { "Nothing" print } } match
See Also: if
Section: 6.5 (Pattern Matching)

not

Operator Type: Logical
Signature: (Logical -- Logical)
Trait: Logical
Description: Logical NOT - inverts truthiness.
Example: false not // => true
See Also: and, or
Section: 4.4 (Logical Operators)

or

Operator Type: Logical
Signature: (Logical Logical -- Logical)
Trait: Logical
Description: Logical OR - returns first if truthy, else second.
Example: true false or // => true
See Also: and, not
Section: 4.4 (Logical Operators)

over

Operator Type: Stack Manipulation
Signature: (Self Self -- Self Self Self)
Trait: Stackable
Description: Copy the second item to the top of the stack.
Example: 5 10 over // => 5 10 5
See Also: dup, swap, rot
Section: 4.1 (Stack Operations)

pick

Operator Type: Stack Manipulation
Signature: (Size -- Self)
Trait: Stackable
Description: Copy nth item to top (0 = top, 1 = second, etc.).
Example: 1 2 3 4 2 pick // => 1 2 3 4 2
See Also: roll, depth
Section: 4.1 (Stack Operations)

reduce

Operator Type: Array Combinator
Signature: (ArrayOf<T> T TokenString -- T)
Description: Fold array with accumulator function.
Example: [1 2 3 4] 0 { + } reduce // => 10
See Also: map, filter, each
Section: 7.4 (Arrays)

reverse

Operator Type: Array
Signature: (ArrayOf<T> -- ArrayOf<T>)
Description: Reverse order of array elements.
Example: [1 2 3] reverse // => [3 2 1]
See Also: transpose, concat
Section: 7.4 (Arrays)

roll

Operator Type: Stack Manipulation
Signature: (Size Size --)
Trait: Stackable
Description: Rotate n items, times times.
Example: 1 2 3 4 3 1 roll // => 1 3 4 2
See Also: rot, pick
Section: 4.1 (Stack Operations)

rot

Operator Type: Stack Manipulation
Signature: (Self Self Self -- Self Self Self)
Trait: Stackable
Description: Rotate the top three items.
Example: 1 2 3 rot // => 2 3 1
See Also: swap, roll
Section: 4.1 (Stack Operations)

set

Operator Type: Struct Access
Signature: (Value Identifier -- Struct)
Description: Set field value in struct (consumes value and field identifier).
Example: 15.0 ::x set
See Also: get
Section: 7.1 (Structs)

shl

Operator Type: Bitwise
Signature: (Bitwise Size -- Bitwise)
Trait: Bitwise
Description: Shift bits left by n positions.
Example: 4 2 shl // => 16
See Also: shr, bitand, bitor
Section: 4.5 (Bitwise Operators)

shr

Operator Type: Bitwise
Signature: (Bitwise Size -- Bitwise)
Trait: Bitwise
Description: Shift bits right by n positions.
Example: 16 2 shr // => 4
See Also: shl, bitand, bitor
Section: 4.5 (Bitwise Operators)

slice

Operator Type: Container
Signature: (Sliceable Size Size -- Sliceable)
Trait: Sliceable
Description: Extract elements from start to end index.
Example: [10 20 30 40] 1 3 slice // => [20 30]
See Also: at, length
Section: 7.4 (Arrays)

struct

Operator Type: Definition
Signature: (TypeTuple TokenString Identifier --)
Trait: Implementable
Description: Define a struct type.
Example: (T T --) { x: y: } ::Point<T> struct
See Also: union, enum, get, set
Section: 7.1 (Structs)

substr

Operator Type: String
Signature: (String Size Size -- String)
Trait: String
Description: Extract substring from start to end index.
Example: "hello" 1 3 substr // => "el"
See Also: slice, split
Section: 11.3 (String Operations)

swap

Operator Type: Stack Manipulation
Signature: (Self Self -- Self Self)
Trait: Stackable
Description: Swap the top two items on the stack.
Example: 5 10 swap // => 10 5
See Also: dup, rot
Section: 4.1 (Stack Operations)

trait

Operator Type: Definition
Signature: (TokenString Identifier --)
Trait: Implementable
Description: Define a new trait.
Example: { (Self -- ) draw: } ::Drawable trait
See Also: impl, inher
Section: 9.2 (Defining Traits)

transpose

Operator Type: Array
Signature: (ArrayOf<ArrayOf<T>> -- ArrayOf<ArrayOf<T>>)
Description: Transpose a 2D array (swap rows and columns).
Example: [[1 2] [3 4]] transpose // => [[1 3] [2 4]]
See Also: reverse
Section: 7.4 (Arrays)

union

Operator Type: Definition
Signature: (TypeTuple TokenString Identifier --)
Trait: Implementable
Description: Define a union type with tagged variants.
Example: (T --) { Some(T) None } ::Option<T> union
See Also: struct, enum, match
Section: 7.2 (Unions)

while

Operator Type: Control Flow
Signature: (TokenString TokenString --)
Description: Loop while condition is truthy, executing body each iteration.
Example: { dup 10 < } { dup print 1 + } while
See Also: for, break, continue, if
Section: 6.2 (While Loops)

window

Operator Type: Array
Signature: (ArrayOf<T> Size -- ArrayOf<ArrayOf<T>>)
Description: Create sliding windows of given size.
Example: [1 2 3 4] 2 window // => [[1 2] [2 3] [3 4]]
See Also: slice
Section: 7.4 (Arrays)


Appendix D: Grammar Summary

This appendix provides a concise grammar reference. For complete specifications of language constructs (fn, struct, trait, impl, etc.), see the ::Implementable trait in Appendix B.

D.1 Lexical Grammar

Comments:

line_comment ::= "//" <any characters until newline>

Identifiers:

identifier ::= [a-zA-Z_][a-zA-Z0-9_]*
identifier_literal ::= "::" identifier

Integer Literals:

integer ::= decimal | hexadecimal | binary
decimal ::= [0-9]+ (":" type_name)?
hexadecimal ::= "0x" [0-9a-fA-F]+
binary ::= "0b" [01]+

Floating Point Literals:

float ::= [0-9]+ "." [0-9]+ (":" type_name)?

String Literals:

string ::= '"' (character | escape_sequence)* '"'
escape_sequence ::= "\n" | "\r" | "\t" | "\\" | '\"' | "\'" | "\0" 
                  | "\x" hex_digit hex_digit 
                  | "\u{" hex_digit+ "}"

Boolean Literals:

boolean ::= "true" | "false"

Array Literals:

array ::= "[" (expression)* "]"

Token Strings:

token_string ::= "{" (token)* "}"

D.2 Expression Grammar

expression ::= literal 
             | identifier 
             | identifier_literal 
             | expression operator
             | control_flow
             | definition

literal ::= integer | float | string | boolean | array

operator ::= built_in_operator | user_defined_operator

control_flow ::= if_expr | while_expr | for_expr | match_expr

Note on Operator Precedence: Stack-based postfix notation eliminates the need for operator precedence. Operations are performed in the order they appear, operating on values already on the stack.

D.3 Type Grammar

Type Tuples (Stack Signatures):

type_tuple ::= "(" type_list "--" type_list ")"
             | "(---)"
type_list ::= (type)*
type ::= identifier 
       | generic_type 
       | trait_constraint

generic_type ::= identifier "<" type_param_list ">"
type_param_list ::= type_param ("," type_param)*
type_param ::= identifier (":" trait_constraint)?

D.4 Construct Grammar

Language constructs (fn, struct, trait, impl, enum, union, inher) are defined by operators in the ::Implementable trait. These operators parse TokenStrings to create language-level definitions.

High-Level Patterns:

  • Functions: (inputs -- outputs) { body } ::name fn
  • Structs: (field_types --) { field_names: } ::name<type_params>? struct
  • Unions: (variant_types --) { Variant(T) ... } ::name<type_params>? union
  • Enums: { Variant value?: ... } ::name enum
  • Traits: { (sig) method: ... } ::identifier<type_params>? trait
  • Trait Impl: ::trait_id { (sig) { body } method: ... } ::type_id<type_params>? impl
  • Trait Inheritance: [ identifier_list ] ::identifier<type_params>? inher { } ::identifier<type_params>? trait

Complete Specification: See Appendix B (::Implementable trait) for precise definitions of these construct operators.


Appendix E: Module System (Future)

Current State: All standard library functions and traits are automatically in scope.

Future Design: A module system for organizing code and managing namespaces.

Proposed Syntax:

// Import entire module (using :: prefix)
::std::math use

// Import specific items
::std::collections::HashMap use

// Import with alias - Option 1: Inline alias
::std::io::File ::F as use

// Import with alias - Option 2: Separate alias operator
::std::io::File ::F use_as

// Import with alias - Option 3: Block syntax
{ ::std::io::File ::F as } use

// Export from current module
::Point ::geometry export
::distance ::geometry export

// Module declaration
::my_module module {
    // Module contents
}

Module Resolution:

  • Standard library: ::std::<module>::<item>
  • User modules: Relative to current file
  • Third-party: Package manager integration (future)

Benefits:

  • Clean namespaces
  • Explicit dependencies
  • Code organization
  • Faster compilation (selective imports)

Appendix F: Memory Management (Future)

The language specification currently does not include heap memory management. This appendix documents potential future approaches.

Current State: All values are stack-allocated or embedded in data structures.

Pointer Types: The ptr type for raw pointers is planned as a future feature and will be part of the memory management system.

Potential Approaches:

Option A: Manual Management

// Allocate on heap
3.0 4.0 Point alloc     // ( Point -- ptr<Point> )

// Dereference
ptr deref               // ( ptr<T> -- T )

// Store through pointer
new_value ptr store     // ( T ptr<T> -- )

// Free memory
ptr free                // ( ptr<T> -- )

Pros: Full control, predictable, zero overhead
Cons: Error-prone, requires discipline, potential memory leaks

Option B: Reference Counting

// Create reference-counted value
3.0 4.0 Point rc        // ( Point -- rc<Point> )

// Automatic reference counting
value dup               // Increments count
drop                    // Decrements count, frees if zero

Pros: Automatic cleanup, relatively simple
Cons: Runtime overhead, cannot handle cycles, larger memory footprint

Option C: Ownership System (Rust-like)

// Linear types - each value has one owner
value                   // Move semantics by default
value dup               // Error: cannot copy owned value
value ::clone call      // Explicit clone required

Pros: Memory safe, zero overhead, prevents leaks
Cons: Complex type system, restricts stack operations, steep learning curve

Option D: Arena/Region-Based

// Create arena
::arena new             // ( -- arena )

// Allocate in arena
arena 3.0 4.0 Point alloc_in  // ( arena Point -- ptr<Point> )

// Free entire arena
arena free_arena        // ( arena -- )

Pros: Fast allocation, simple bulk deallocation
Cons: Less granular control, memory held until arena freed

Recommendation: Start without heap allocation (current approach). When needed, implement Option A (manual) for simplicity, with Option D (arenas) added later for performance-critical code. The stack-based nature makes ownership tracking (Option C) particularly challenging.

Type Parameter Enforcement Enhancement:

Current State: Type parameters in generic functions are currently suggestions and are not enforced at parse time.

Example:

(T -- T) { dup * } ::square fn  // Currently no error even without Multiplyable constraint

Future Enhancement: The compiler could enforce that type parameters actually constrain how operators and functions act, validated at parse time:

(Multiplyable -- Multiplyable) { dup * } ::square fn  // Enforced constraint

This would provide stronger type safety but add complexity to the type checker.


Appendix G: Examples & Tutorials

G.1 Tutorial: First Steps

Hello World:

"Hello, World!" print

Basic Arithmetic:

// Simple calculations
3 4 +           // => 7
10 3 -          // => 7
5 6 *           // => 30
20 4 /          // => 5

// Chaining operations
2 3 + 4 *       // => 20 (addition happens first due to postfix order)

// Using the stack
10 dup *        // => 100 (duplicate 10, then multiply)

Simple Functions:

// Square function
(Number -- Number) { dup * } ::square fn
5 square        // => 25

// Absolute value
(Number -- Number) {
    dup 0 >
        { }                     // If positive, do nothing
        { 0 swap - }            // If negative, negate
    if
} ::abs fn

-5 abs          // => 5

Stack Manipulation Practice:

// Basic stack operations
5 dup           // => 5 5
5 10 swap       // => 10 5
5 10 over       // => 5 10 5
1 2 3 rot       // => 2 3 1

// More complex example - swap two items below top
// Stack: a b c
// Want: b a c
rot rot         // First rot: b c a, Second rot: c a b... wait, that's wrong!

// Better approach:
// Stack: a b c
swap rot rot    // swap: a c b, rot: c b a, rot: b a c (correct!)

G.2 Tutorial: Working with Traits

Implementing a Trait for a Custom Type:

// Step 1: Define a struct
(Number Number --) { x: y: } ::Point struct

// Step 2: Implement Addable trait
::Addable {
    // Add two points
    (Self Self -- Self) {
        over ::x get over ::x get +    // Add x coordinates
        swap ::y get swap ::y get +    // Add y coordinates
        Point                           // Construct new point
    } +:

    // Subtract two points
    (Self Self -- Self) {
        over ::x get over ::x get -    // Subtract x coordinates
        swap ::y get swap ::y get -    // Subtract y coordinates
        Point                           // Construct new point
    } -:
} ::Point impl

// Step 3: Use it
3.0 4.0 Point                          // First point
1.0 2.0 Point                          // Second point
+                                      // => Point with x=4.0, y=6.0

Using Trait Bounds:

// Function that works with any Addable type
(Addable Addable Addable -- Addable) {
    + +                                 // Add all three
} ::sum_three fn

// Works with numbers
1 2 3 sum_three                        // => 6

// Works with Points
1.0 2.0 Point
3.0 4.0 Point
5.0 6.0 Point
sum_three                              // => Point(9.0, 12.0)

Understanding Standard Traits:

// Number trait combines many operations
(Number Number -- Number) {
    dup * swap dup * +                 // a² + b²
} ::pythagorean fn

3.0 4.0 pythagorean                    // => 25.0

// This works because Number inherits from:
// - Addable (for +)
// - Multiplyable (for *)
// - Comparable (for comparisons)
// - And more...

G.3 Tutorial: Generic Programming

Writing Generic Functions:

// Generic identity - works with any type
(T -- T) { } ::identity fn

5 identity                             // => 5
"hello" identity                       // => "hello"

// Generic swap function
(T U -- U T) { swap } ::generic_swap fn

// Constrained generic - requires Comparable
(Comparable Comparable -- Comparable) {
    over over >
        { }                            // First is larger, do nothing
        { swap }                       // Second is larger, swap them
    if
    drop                               // Drop the smaller value
} ::max fn

5 10 max                               // => 10
10 5 max                               // => 10

Generic Data Structures:

// Define a generic Pair
(T U --) { first: second: } ::Pair<T U> struct

// Use with different types
5 "hello" Pair                         // Pair<i64, String>
3.14 true Pair                         // Pair<f64, bool>

// Access fields
dup ::first get                        // Get first element
::second get                           // Get second element

// Generic Option (already defined in standard library)
(T --) { Some(T) None } ::Option<T> union

42 Option::Some                        // Option<i64>::Some
Option::None                           // Option<T>::None

Trait Constraints in Generics:

// This function requires the type to be Multiplyable
(T:Multiplyable -- T) {
    dup *
} ::square_generic fn

// Works with any Multiplyable type
5 square_generic                       // => 25
3.14 square_generic                    // => 9.8596

// Multiple constraints using composite traits
(Number -- Number) {
    dup 0 >
        { }
        { 0 swap - }
    if
} ::abs_generic fn

G.4 Complete Examples

G.4.1 Trait Implementation Example

// Define a trait for drawable objects
{
    (Self -- ) draw:
} ::Drawable trait

// Define a Rectangle struct
(Number Number --) { width: height: } ::Rectangle struct

// Implement Drawable for Rectangle
::Drawable {
    (Self -- ) {
        "Drawing rectangle:" print
        dup ::width get "Width: " swap concat print
        ::height get "Height: " swap concat print
    } draw:
} ::Rectangle impl

// Use it
10.0 20.0 Rectangle draw
// Output:
// Drawing rectangle:
// Width: 10.0
// Height: 20.0

G.4.2 Trait Inheritance Example

// Define base traits
{
    (Self Self -- Self) +:
    (Self Self -- Self) -:
} ::Addable trait

{
    (Self Self -- Self) *:
    (Self Self -- Self) /:
} ::Multiplyable trait

// Composite trait inheriting from both
[ ::Addable ::Multiplyable ] ::BasicMath inher
{ } ::BasicMath trait

// Now any type implementing BasicMath must support +, -, *, /
// And functions can require BasicMath as a constraint
(BasicMath BasicMath -- BasicMath) {
    over over * swap dup * +           // (a * b) + (b * b)
} ::weird_math fn

3 4 weird_math                         // => 28

G.4.3 Logarithm Usage

// Calculate log base 10
100 log print       // => 2.0
1000 log print      // => 3.0

// Calculate natural logarithm
2.718 ln print      // => ~1.0
7.389 ln print      // => ~2.0

// Calculate with custom base
8 2 logb print      // => 3.0 (2³ = 8)
27 3 logb print     // => 3.0 (3³ = 27)

// Combine with other operations
10 3 ^ log print    // => 3.0 (log of 1000)

// Logarithm laws verification
// log(a*b) = log(a) + log(b)
10 100 * log        // log(1000) = 3.0
10 log 100 log +    // log(10) + log(100) = 1.0 + 2.0 = 3.0

G.4.4 Factorial

(Number -- Number) {
    dup 1 <=
        { drop 1 }                     // Base case: 0! = 1! = 1
        { dup 1 - factorial * }        // Recursive case: n! = n * (n-1)!
    if
} ::factorial fn

5 factorial print       // => 120
10 factorial print      // => 3628800

// Iterative version (more efficient)
(Number -- Number) {
    1 swap                             // Start with accumulator = 1
    1 swap                             // Start counter at 1
    {                                  // While counter <= n
        dup 3 pick <=
    }
    {                                  // Body: multiply accumulator by counter
        2 pick over *                  // acc * counter
        3 roll drop                    // Drop old accumulator
        swap 1 + swap                  // Increment counter
    }
    while
    drop                               // Drop counter
    swap drop                          // Drop original n
} ::factorial_iter fn

5 factorial_iter print  // => 120

G.4.5 FizzBuzz

(Number -- ) {
    dup 15 % 0 ==
        { drop "FizzBuzz" print }
        {
            dup 3 % 0 ==
                { drop "Fizz" print }
                {
                    dup 5 % 0 ==
                        { drop "Buzz" print }
                        { print }
                    if
                }
            if
        }
    if
} ::fizzbuzz fn

// Print FizzBuzz for 1 to 100
1 100 { fizzbuzz } for

G.4.6 Using Roll

// Roll rotates the top n items, times times
// Stack: 1 2 3 4 5

// Rotate top 3 items once
3 1 roll    // Stack: 1 2 4 5 3

// Start fresh: 1 2 3 4 5
// Rotate top 3 items twice
3 2 roll    // Stack: 1 2 5 3 4

// Start fresh: 1 2 3 4 5
// Rotate all 5 items once
5 1 roll    // Stack: 2 3 4 5 1

// Start fresh: 1 2 3 4 5
// Rotate top 4 items three times
4 3 roll    // Stack: 1 4 5 2 3

// Practical use: bring nth item to top
// Stack: a b c d e
// Want to bring 'b' (index 3) to top
4 3 roll    // Rotates top 4 three times: a c d e b

// Or use pick for non-destructive copy
// Stack: a b c d e
3 pick      // Stack: a b c d e b (copied from index 3)

G.4.7 Array Processing

// Sum of squares of even numbers from 1 to 10
[1 2 3 4 5 6 7 8 9 10]
    { 2 % 0 == } filter                // Keep even: [2 4 6 8 10]
    { dup * } map                      // Square each: [4 16 36 64 100]
    0 { + } reduce                     // Sum: 220
print

// Find maximum in array
[5 2 9 1 7 6]
    dup 0 at                           // Start with first element
    { 
        over over >
            { swap }                   // If current > max, swap
            { }                        // Otherwise keep max
        if
        drop                           // Drop the smaller value
    } reduce
print                                  // => 9

// Average of array
[10 20 30 40 50]
    dup 0 { + } reduce                // Sum: 150
    swap length                        // Length: 5
    /                                  // Average: 30
print

G.4.8 Identifier Literals in Practice

// Identifier literals are used in struct/trait definitions
// and field access

// Defining a struct requires ::StructName identifier literal
(Number Number --) { x: y: } ::Point struct

// Field access requires ::field_name identifier literal
3.0 4.0 Point
dup ::x get print                      // Prints: 3.0
::y get print                          // Prints: 4.0

// Dynamic field access (advanced)
"x" ::                                 // Convert string to identifier
// (This would require string-to-identifier conversion, which
//  may be a future feature)

// Traits use identifier literals
{ (Self -- ) draw: } ::Drawable trait

// Implementations use identifier literals
::Drawable { ... } ::Rectangle impl

// Identifier literals are NOT used inside trait/impl bodies
// (those are method names)
{
    (Self -- ) { "Drawing" print } draw:  // "draw:" is method name
} ::Drawable trait

End of Stack Language Specification v0.8