G Examples & Tutorials


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 Mathematical Functions Usage

// Square root
16 sqrt print       // => 4.0
2.0 sqrt print      // => ~1.414

// Trigonometric functions
0.0 sin print       // => 0.0
0.0 cos print       // => 1.0
1.0 atan print      // => ~0.7854

// Rounding functions
3.14 floor print    // => 3.0
3.14 ceil print     // => 4.0
3.7 round print     // => 4.0

// Min/max
3 5 min print       // => 3
3 5 max print       // => 5

// Absolute value
-42 abs print       // => 42

// Random numbers
rand print          // => 0.7234... (random)
12345 seed          // Seed for deterministic results
rand print          // => 0.4321... (deterministic after seed)

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

// Or use built-in functions
[10 20 30 40 50] mean print           // => 30.0
[1 2 3 4 5] sum print                 // => 15

// Zip and enumerate
[1 2 3] [4 5 6] zip print             // => [[1 4] [2 5] [3 6]]
["a" "b" "c"] enumerate print         // => [[0 "a"] [1 "b"] [2 "c"]]

G.4.8 String Operations

// String manipulation
"hello" " world" concat print         // => "hello world"
"hello" 1 3 substr print              // => "el"
"a,b,c" "," split print               // => ["a" "b" "c"]
["a" "b" "c"] "," join print          // => "a,b,c"

// String searching
"hello world" "world" find            // => Option::Some(6)
"hello" "hel" starts_with print       // => true
"hello" "lo" ends_with print          // => true

// String modification
"hello world" "world" "Stack" replace print  // => "hello Stack"
"  hello  " trim print                       // => "hello"

// String formatting
"x=%d, y=%d" [5 10] format print     // => "x=5, y=10"
"Name: %s, Age: %d" ["Alice" 30] format print  // => "Name: Alice, Age: 30"

G.4.9 Reflection Examples

// Type checking
(Self -- ) {
    dup type_of to_str "Type: " swap concat print

    dup ::Addable implements
        { "Supports addition" print }
        { "Does not support addition" print }
    if

    dup ::Stringifiable implements
        { to_str print }
        { drop "Cannot convert to string" print }
    if
} ::debug_print fn

42 debug_print
// Output:
// Type: i64
// Supports addition
// 42

// Dynamic dispatch based on traits
(Self -- ) {
    dup ::Drawable implements
        { draw }
        { drop "Not drawable" print }
    if
} ::try_draw fn

// Generic type information
(Self -- String) {
    type_of to_str
} ::type_name fn

42 type_name print           // => "i64"
"hello" type_name print      // => "String"
[1 2 3] type_name print      // => "Array<i64>"

G.4.10 Testing Examples

// Simple assertions
{ 2 3 + } { 5 == } assert
{ 5 square } { 25 == } assert

// Testing a function thoroughly
(Number -- Number) { dup * } ::square fn

// Test with multiple values
{ 0 square } { 0 == } assert
{ 1 square } { 1 == } assert
{ 5 square } { 25 == } assert
{ -3 square } { 9 == } assert

// Testing edge cases
(Number Number -- Number) { / } ::divide fn

// This will pass
{ 10 2 divide } { 5 == } assert

// This will halt (division by zero should be handled)
// { 10 0 divide } { ... } assert  // Don't do this!

// Testing string operations
{ "hello" " world" concat } { "hello world" == } assert
{ "hello" length } { 5 == } assert
{ "hello" 1 3 substr } { "el" == } assert

G.4.11 Constants Example

// Define mathematical constants
3.1415926535 ::pi const
2.7182818284 ::e const
1.6180339887 ::phi const

// Use in calculations
(Number -- Number) {
    dup * pi *                         // Area = r² * π
} ::circle_area fn

5 circle_area print                    // => ~78.54

// Physical constants
299792458 ::speed_of_light const       // m/s
9.81 ::gravity const                   // m/s²

// Use in physics calculations
(Number -- Number) {
    dup * 2 / gravity *                // E = mgh where h = v²/2g
} ::kinetic_to_potential fn

10 kinetic_to_potential print          // => ~490.5