YREA-SLS/docs/examples_and_tutorials.md

433 lines
10 KiB
Markdown

---
Title: YREA SLS | G Examples & Tutorials
Prev: Memory Management
Next:
---
## 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
```
---