diff options
Diffstat (limited to 'js/scripting-lang/tutorials/12_IO_Operations.md')
-rw-r--r-- | js/scripting-lang/tutorials/12_IO_Operations.md | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/js/scripting-lang/tutorials/12_IO_Operations.md b/js/scripting-lang/tutorials/12_IO_Operations.md new file mode 100644 index 0000000..de22f0a --- /dev/null +++ b/js/scripting-lang/tutorials/12_IO_Operations.md @@ -0,0 +1,208 @@ +# IO Operations + +## What are IO Operations? + +IO (Input/Output) operations allow your functional programs to interact with the outside world. Baba Yaga provides a minimal set of IO operations that keep side effects contained and explicit. + +## Basic Output + +### Simple Output +```plaintext +/* Output values to console */ +..out "Hello, World!"; +..out 42; +..out true; +..out {name: "Alice", age: 30}; +``` + +### Output with Expressions +```plaintext +/* Output computed values */ +result : 5 + 3 * 2; +..out result; /* Output: 11 */ + +/* Output function results */ +double : x -> x * 2; +..out double 7; /* Output: 14 */ + +/* Output table operations */ +numbers : {1, 2, 3, 4, 5}; +doubled : map @double numbers; +..out doubled; /* Output: {2, 4, 6, 8, 10} */ +``` + +## Assertions + +Assertions help you verify your program's behavior: + +```plaintext +/* Basic assertions */ +..assert 5 = 5; /* Passes */ +..assert 3 + 2 = 5; /* Passes */ +..assert true; /* Passes */ +..assert false; /* Fails with error */ + +/* Assertions with messages */ +..assert "5 equals 5" 5 = 5; /* Passes */ +..assert "3 + 2 equals 5" 3 + 2 = 5; /* Passes */ +..assert "This will fail" 1 = 2; /* Fails with message */ +``` + +### Testing Functions +```plaintext +/* Test function behavior */ +factorial : n -> + when n is + 0 then 1 + _ then n * (factorial (n - 1)); + +/* Test cases */ +..assert "factorial 0 = 1" factorial 0 = 1; +..assert "factorial 1 = 1" factorial 1 = 1; +..assert "factorial 5 = 120" factorial 5 = 120; +``` + +## Emit and Listen Pattern + +The `..emit` and `..listen` pattern provides a way to interface functional code with external systems: + +### Emitting Events +```plaintext +/* Emit events with data */ +..emit "user_created" {id: 123, name: "Alice"}; +..emit "data_processed" {count: 42, success: true}; +..emit "error_occurred" {message: "Invalid input", code: 400}; +``` + +### Listening for Events +```plaintext +/* Listen for specific events */ +..listen "user_created" handle_user_created; +..listen "data_processed" handle_data_processed; +..listen "error_occurred" handle_error; +``` + +### Event Handlers +```plaintext +/* Define event handlers */ +handle_user_created : user_data -> + ..out "New user created:"; + ..out user_data.name; + +handle_data_processed : result -> + when result.success is + true then ..out "Processing successful: " + result.count + " items" + false then ..out "Processing failed"; + +handle_error : error -> + ..out "Error: " + error.message; + ..out "Code: " + error.code; +``` + +## Input Operations + +### Reading Input +```plaintext +/* Read input from user */ +name : ..in "Enter your name: "; +..out "Hello, " + name + "!"; + +/* Read and process input */ +age_input : ..in "Enter your age: "; +age : parseInt age_input; +..out "You are " + age + " years old"; +``` + +## IO Best Practices + +### Keep Side Effects Explicit +```plaintext +/* Good: Clear IO operations */ +process_data : data -> + result : transform data; + ..out "Processing complete"; + ..emit "data_processed" result; + result; + +/* Avoid: Hidden side effects in pure functions */ +bad_transform : data -> + ..out "Processing..."; /* Side effect in "pure" function */ + data * 2; +``` + +### Use Assertions for Testing +```plaintext +/* Test your functions thoroughly */ +is_even : x -> x % 2 = 0; +double : x -> x * 2; + +/* Test individual functions */ +..assert "0 is even" is_even 0 = true; +..assert "1 is not even" is_even 1 = false; +..assert "double 5 = 10" double 5 = 10; + +/* Test composed functions */ +doubled_evens : compose @double @is_even; +..assert "doubled_evens 6 = true" doubled_evens 6 = true; +``` + +### Structured Output +```plaintext +/* Use tables for structured output */ +user : {name: "Alice", age: 30, city: "NYC"}; +..out "User Profile:"; +..out " Name: " + user.name; +..out " Age: " + user.age; +..out " City: " + user.city; + +/* Or output the entire structure */ +..out user; +``` + +## Common Patterns + +### Data Processing Pipeline +```plaintext +/* Process data with IO feedback */ +data : {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; +..out "Processing " + t.length data + " items"; + +is_even : x -> x % 2 = 0; +double : x -> x * 2; +sum : x -> reduce @add 0 x; + +/* Process with progress updates */ +evens : filter @is_even data; +..out "Found " + t.length evens + " even numbers"; + +doubled : map @double evens; +..out "Doubled values:"; +..out doubled; + +total : sum doubled; +..out "Sum of doubled evens: " + total; + +/* Emit final result */ +..emit "processing_complete" {input_count: t.length data, result: total}; +``` + +### Error Handling +```plaintext +/* Handle potential errors gracefully */ +safe_divide : x y -> + when y = 0 then + ..emit "division_error" {dividend: x, divisor: y}; + "Error: Division by zero" + _ then x / y; + +/* Test error handling */ +..out safe_divide 10 2; /* 5 */ +..out safe_divide 10 0; /* Error: Division by zero */ +``` + +## Next Steps + +Now that you understand IO operations, explore: +- [Error Handling](13_Error_Handling.md) for robust error management +- [Integration Patterns](15_Integration_Patterns.md) for external system integration +- [Best Practices](16_Best_Practices.md) for writing clean code \ No newline at end of file |