538 lines
13 KiB
Markdown
538 lines
13 KiB
Markdown
---
|
|
Title: G Examples & Tutorials
|
|
Prev: Memory Management
|
|
Next:Complete Type Reference
|
|
---
|
|
|
|
## 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
|
|
```
|
|
|
|
---
|