YREA-SLS/docs/examples_and_tutorials.md

10 KiB

Title Prev Next
G Examples & Tutorials Memory Management

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