about summary refs log tree commit diff stats
path: root/js/scripting-lang/tutorials/06_Immutable_Tables.md
diff options
context:
space:
mode:
Diffstat (limited to 'js/scripting-lang/tutorials/06_Immutable_Tables.md')
-rw-r--r--js/scripting-lang/tutorials/06_Immutable_Tables.md251
1 files changed, 251 insertions, 0 deletions
diff --git a/js/scripting-lang/tutorials/06_Immutable_Tables.md b/js/scripting-lang/tutorials/06_Immutable_Tables.md
new file mode 100644
index 0000000..8502603
--- /dev/null
+++ b/js/scripting-lang/tutorials/06_Immutable_Tables.md
@@ -0,0 +1,251 @@
+# Immutable Tables with Functional Operations
+
+## What are Immutable Tables?
+
+Immutable tables are data structures that **cannot be modified after creation**. All operations on tables return **new tables** rather than modifying the original.
+
+```plaintext
+/* All table operations return new tables */
+original : {a: 1, b: 2, c: 3};
+modified : t.set original "d" 4;  /* Returns new table */
+/* original is unchanged: {a: 1, b: 2, c: 3} */
+/* modified is: {a: 1, b: 2, c: 3, d: 4} */
+```
+
+## Why is This Esoteric?
+
+Most programming languages allow direct modification of data structures. Our language enforces **complete immutability** - no mutation operations exist at all.
+
+## Basic Examples
+
+```plaintext
+/* Create a table */
+original : {name: "Alice", age: 30, city: "New York"};
+
+/* All operations return new tables */
+with_job : t.set original "job" "Engineer";
+with_updated_age : t.set original "age" 31;
+without_city : t.delete original "city";
+
+/* Original table is unchanged */
+/* original is still {name: "Alice", age: 30, city: "New York"} */
+```
+
+## Table Operations
+
+### Setting Values
+```plaintext
+/* t.set table key value - returns new table with key set */
+data : {a: 1, b: 2};
+updated : t.set data "c" 3;
+/* updated: {a: 1, b: 2, c: 3} */
+/* data: {a: 1, b: 2} (unchanged) */
+```
+
+### Deleting Keys
+```plaintext
+/* t.delete table key - returns new table without the key */
+data : {a: 1, b: 2, c: 3};
+without_b : t.delete data "b";
+/* without_b: {a: 1, c: 3} */
+/* data: {a: 1, b: 2, c: 3} (unchanged) */
+```
+
+### Merging Tables
+```plaintext
+/* t.merge table1 table2 - returns new table with combined keys */
+table1 : {a: 1, b: 2};
+table2 : {c: 3, d: 4};
+merged : t.merge table1 table2;
+/* merged: {a: 1, b: 2, c: 3, d: 4} */
+/* table1 and table2 unchanged */
+```
+
+### Getting Values
+```plaintext
+/* t.get table key - returns value (doesn't modify table) */
+data : {name: "Alice", age: 30};
+name : t.get data "name";  /* "Alice" */
+age : t.get data "age";    /* 30 */
+/* data unchanged */
+```
+
+### Checking Keys
+```plaintext
+/* t.has table key - returns boolean (doesn't modify table) */
+data : {name: "Alice", age: 30};
+has_name : t.has data "name";    /* true */
+has_job : t.has data "job";      /* false */
+/* data unchanged */
+```
+
+## Element-Wise Operations
+
+All element-wise operations return new tables:
+
+```plaintext
+/* map returns new table - @ operator required for higher-order functions */
+numbers : {a: 1, b: 2, c: 3};
+double : x -> x * 2;
+doubled : map @double numbers;  /* {a: 2, b: 4, c: 6} */
+/* numbers unchanged: {a: 1, b: 2, c: 3} */
+
+/* filter returns new table - @ operator required for higher-order functions */
+is_greater_than_one : x -> x > 1;
+filtered : filter @is_greater_than_one numbers;  /* {b: 2, c: 3} */
+/* numbers unchanged: {a: 1, b: 2, c: 3} */
+```
+
+## Complex Examples
+
+```plaintext
+/* Building complex tables immutably */
+base_user : {name: "Alice", age: 30};
+
+/* Add multiple properties */
+with_email : t.set base_user "email" "alice@example.com";
+with_address : t.set with_email "address" "123 Main St";
+with_phone : t.set with_address "phone" "555-1234";
+
+/* Or merge with another table */
+contact_info : {email: "alice@example.com", phone: "555-1234"};
+complete_user : t.merge base_user contact_info;
+/* Result: {name: "Alice", age: 30, email: "alice@example.com", phone: "555-1234"} */
+```
+
+## Nested Tables
+
+Immutability works with nested table structures:
+
+```plaintext
+/* Nested table */
+user : {
+  name: "Alice",
+  profile: {
+    age: 30,
+    preferences: {
+      theme: "dark",
+      notifications: true
+    }
+  }
+};
+
+/* Update nested property - creates new nested structure */
+updated_preferences : t.set user.profile.preferences "theme" "light";
+/* This creates new tables at each level */
+/* user unchanged, updated_preferences has new nested structure */
+```
+
+## Functional Programming Patterns
+
+Immutability enables pure functional programming patterns:
+
+```plaintext
+/* Pure function - no side effects */
+update_age : user new_age -> t.set user "age" new_age;
+
+/* Multiple updates create new tables */
+user1 : {name: "Alice", age: 30};
+user2 : update_age user1 31;
+user3 : update_age user2 32;
+
+/* All tables exist independently */
+/* user1: {name: "Alice", age: 30} */
+/* user2: {name: "Alice", age: 31} */
+/* user3: {name: "Alice", age: 32} */
+```
+
+## When to Use Immutable Tables
+
+**Use immutable tables when:**
+- You want to prevent accidental data modification
+- You're building functional programming patterns
+- You need to track data changes over time
+- You want to ensure thread safety (if applicable)
+- You're working with complex data transformations
+
+**Don't use immutable tables when:**
+- You need to modify data in place for performance reasons
+- You're working with very large datasets that can't be copied
+- You need to perform side effects on data structures
+
+## Common Patterns
+
+```plaintext
+/* Pattern 1: Building up data structures */
+base_config : {debug: false, timeout: 30};
+
+/* Add development settings */
+dev_config : t.merge base_config {
+  debug: true,
+  log_level: "verbose"
+};
+
+/* Add production settings */
+prod_config : t.merge base_config {
+  timeout: 60,
+  cache_enabled: true
+};
+
+/* Pattern 2: Data transformation pipeline */
+user_data : {name: "Alice", age: 30, scores: {85, 90, 88}};
+
+/* Transform user data */
+with_average : t.set user_data "average_score" (reduce @add 0 user_data.scores / 3);
+with_grade : t.set with_average "grade" (when with_average.average_score is
+  when with_average.average_score >= 90 then "A"
+  when with_average.average_score >= 80 then "B"
+  _ then "C");
+
+/* Pattern 3: State management */
+initial_state : {count: 0, items: {}};
+
+/* State transitions */
+increment_state : state -> t.set state "count" (state.count + 1);
+add_item_state : state item -> t.set state "items" (t.set state.items item.id item);
+
+/* Apply transitions */
+state1 : increment_state initial_state;
+state2 : add_item_state state1 {id: "item1", name: "First Item"};
+```
+
+## Performance Considerations
+
+```plaintext
+/* Immutability can be expensive for large tables */
+large_table : {/* ... many entries ... */};
+
+/* Each operation creates a new copy */
+updated1 : t.set large_table "key" "value";
+updated2 : t.set updated1 "key2" "value2";
+/* This creates multiple copies of the large table */
+
+/* Consider batching operations */
+batch_update : table -> t.merge table {
+  key1: "value1",
+  key2: "value2",
+  key3: "value3"
+};
+/* Single operation instead of multiple */
+```
+
+## Key Takeaways
+
+1. **Complete immutability** - no mutation operations exist
+2. **New tables returned** - all operations return new data structures
+3. **Original unchanged** - source tables are never modified
+4. **Functional patterns** - enables pure functional programming
+5. **Composable operations** - operations can be chained safely
+6. **@ operator required** - for higher-order functions like `map`, `filter`, `reduce`
+
+## Why This Matters
+
+Immutable tables make the language safer and more functional:
+
+- **No side effects** - functions can't accidentally modify data
+- **Predictable behavior** - data never changes unexpectedly
+- **Functional style** - encourages pure functions and composition
+- **Debugging ease** - data state is always predictable
+- **Thread safety** - no shared mutable state issues
+
+This feature makes the language feel more like pure functional languages like Haskell! 🚀 
\ No newline at end of file