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