diff options
Diffstat (limited to 'js/scripting-lang/tutorials/00_Introduction.md')
-rw-r--r-- | js/scripting-lang/tutorials/00_Introduction.md | 434 |
1 files changed, 434 insertions, 0 deletions
diff --git a/js/scripting-lang/tutorials/00_Introduction.md b/js/scripting-lang/tutorials/00_Introduction.md new file mode 100644 index 0000000..cfd2c80 --- /dev/null +++ b/js/scripting-lang/tutorials/00_Introduction.md @@ -0,0 +1,434 @@ +# Tutorial: Learning the Scripting Language + +This guide will teach you how to use this functional programming language, assuming you have basic programming knowledge and a passing familiarity with functional programming concepts. + +## What You'll Learn + +By the end of this tutorial, you'll be able to: + +- Write basic programs with functions and data +- Use pattern matching for conditional logic (our only control flow) +- Work with tables (our only data structures) +- Apply functional programming patterns +- Use the standard library's combinators + +## Getting Started + +### Running Your First Program + +Create a file called `hello.txt` with this content: + +```plaintext +/* Your first program */ +..out "Hello, World!"; +``` + +Run it with: +```bash +node lang.js hello.txt +``` + +You should see: `Hello, World!` + +### Basic Values and Variables + +The language supports numbers, strings, and booleans: + +```plaintext +/* Basic values */ +name : "Lucy Snowe"; +age : 18; +is_student : true; + +/* Output values */ +..out name; +..out age; +..out is_student; +``` + +**Key Point**: Variables are immutable - once assigned, they cannot be changed. + +## Functions: The Building Blocks + +### Defining Functions + +Functions are defined using arrow syntax: + +```plaintext +/* Simple function */ +double : x -> x * 2; + +/* Function with multiple parameters */ +add : x y -> x + y; + +/* Using functions */ +result : double 5; +sum : add 3 4; +..out result; /* Output: 10 */ +..out sum; /* Output: 7 */ +``` + +### Function Application + +Functions are applied by putting the function name followed by arguments: + +```plaintext +/* Function application */ +square : x -> x * x; +result : square 5; +..out result; /* Output: 25 */ + +/* Multiple applications */ +double : x -> x * 2; +increment : x -> x + 1; +result : increment (double 5); +..out result; /* Output: 11 */ +``` + +**Key Point**: Unary minus works without parentheses: `f -5` applies `f` to `negate(5)`. Use spaces around binary operators for clarity: `5 - 3` for subtraction. See the [Juxtaposition tutorial](01_Juxtaposition_Function_Application.md#negative-numbers-and-spacing) for detailed information about operator spacing. + +## Pattern Matching with `when` + +Instead of if/else statements, we use pattern matching: + +```plaintext +/* Basic pattern matching */ +classify : x -> + when x is + 0 then "zero" + 1 then "one" + _ then "other"; + +/* Using the function */ +..out (classify 0); /* Output: "zero" */ +..out (classify 1); /* Output: "one" */ +..out (classify 5); /* Output: "other" */ +``` + +The `_` is a wildcard that matches anything. + +### Multiple Value Patterns + +You can match on multiple values: + +```plaintext +/* Multiple value patterns */ +compare : x y -> + when x y is + 0 0 then "both zero" + 0 _ then "x is zero" + _ 0 then "y is zero" + _ _ then "neither zero"; + +/* Using the function */ +..out (compare 0 0); /* Output: "both zero" */ +..out (compare 0 5); /* Output: "x is zero" */ +..out (compare 3 0); /* Output: "y is zero" */ +..out (compare 3 5); /* Output: "neither zero" */ +``` + +## Tables: Our Data Structures + +Tables are like objects or dictionaries in other languages: + +```plaintext +/* Creating tables */ +person : {name: "Alice", age: 30, city: "NYC"}; +numbers : {1, 2, 3, 4, 5}; + +/* Accessing values */ +..out person.name; +..out person["age"]; +..out numbers[1]; /* Note: indexing starts at 1 */ +``` + +### Table Operations + +Tables support element-wise operations: + +```plaintext +/* Transform every value in a table */ +double : x -> x * 2; +numbers : {1, 2, 3, 4, 5}; +doubled : map @double numbers; +..out doubled[1]; /* Output: 2 */ +..out doubled[2]; /* Output: 4 */ + +/* Filter values in a table */ +is_even : x -> x % 2 = 0; +evens : filter @is_even numbers; +..out evens[2]; /* Output: 2 */ +..out evens[4]; /* Output: 4 */ +``` + +**Key Point**: The `@` symbol creates a function reference, which is needed for higher-order functions. + +## Function Composition + +### Combining Functions + +You can combine functions to create new ones: + +```plaintext +/* Function composition */ +double : x -> x * 2; +increment : x -> x + 1; + +/* Right-to-left composition (like the (mostly) regular mathematical style) */ +double_then_increment : compose @increment @double; +result : double_then_increment 5; +..out result; /* Output: 11 (5*2=10, then 10+1=11) */ + +/* Left-to-right composition (pipeline style) */ +increment_then_double : pipe @increment @double; +result : increment_then_double 5; +..out result; /* Output: 12 (5+1=6, then 6*2=12) */ +``` + +### The `via` Operator + +The language has a special `via` operator for composition: + +```plaintext +/* Using the via operator */ +double : x -> x * 2; +increment : x -> x + 1; +square : x -> x * x; + +/* This is equivalent to compose */ +result : double via increment via square 3; +..out result; /* Output: 20 (3^2=9, 9+1=10, 10*2=20) */ +``` + +## Working with Multiple Tables + +### Element-wise Operations + +The `each` combinator lets you combine multiple tables: + +```plaintext +/* Element-wise addition */ +table1 : {a: 1, b: 2, c: 3}; +table2 : {a: 10, b: 20, c: 30}; +sum : each @add table1 table2; +..out sum.a; /* Output: 11 */ +..out sum.b; /* Output: 22 */ +..out sum.c; /* Output: 33 */ + +/* Adding a scalar to every element */ +numbers : {1, 2, 3, 4, 5}; +incremented : each @add numbers 10; +..out incremented[1]; /* Output: 11 */ +..out incremented[2]; /* Output: 12 */ +``` + +## Immutable Table Operations + +The `t.` namespace provides immutable table operations: + +```plaintext +/* Creating and modifying tables */ +person : {name: "Alice", age: 30}; + +/* Immutable update */ +updated : t.set person "age" 31; +..out updated.age; /* Output: 31 */ +..out person.age; /* Output: 30 (original unchanged) */ + +/* Immutable merge */ +updates : {age: 32, city: "NYC"}; +merged : t.merge person updates; +..out merged.age; /* Output: 32 */ +..out merged.city; /* Output: "NYC" */ +..out merged.name; /* Output: "Alice" */ + +/* Safe access with defaults */ +name : t.get person "name" "Unknown"; +city : t.get person "city" "Unknown"; +..out name; /* Output: "Alice" */ +..out city; /* Output: "Unknown" */ +``` + +## Recursive Functions + +Functions can call themselves: + +```plaintext +/* Factorial function */ +factorial : n -> + when n is + 0 then 1 + _ then n * (factorial (n - 1)); + +/* Using factorial */ +..out factorial 5; /* Output: 120 */ +..out factorial 0; /* Output: 1 */ +``` + +## Practical Examples + +### Data Processing Pipeline + +```plaintext +/* Processing a list of numbers */ +numbers : {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + +/* Filter even numbers, double them, then sum */ +is_even : x -> x % 2 = 0; +double : x -> x * 2; + +/* Pipeline: filter -> map -> reduce */ +evens : filter @is_even numbers; +doubled : map @double evens; +total : reduce @add 0 doubled; + +..out total; /* Output: 60 (2+4+6+8+10)*2 = 60 */ +``` + +### Table Transformation + +```plaintext +/* Working with structured data */ +people : { + alice: {name: "Alice", age: 30, city: "NYC"}, + bob: {name: "Bob", age: 25, city: "LA"}, + charlie: {name: "Charlie", age: 35, city: "Chicago"} +}; + +/* Extract all ages */ +get_age : person -> person.age; +ages : map @get_age people; +..out ages.alice; /* Output: 30 */ +..out ages.bob; /* Output: 25 */ + +/* Find people over 30 */ +is_over_30 : person -> person.age > 30; +seniors : filter @is_over_30 people; +..out seniors.charlie.name; /* Output: "Charlie" */ +``` + +## Common Patterns + +### Partial Application + +Functions can be partially applied: + +```plaintext +/* Creating specialized functions */ +add : x y -> x + y; +add_ten : add 10; + +/* Using the specialized function */ +..out (add_ten 5); /* Output: 15 */ +..out (add_ten 20); /* Output: 30 */ +``` + +### Function References + +Use `@` to pass functions as arguments: + +```plaintext +/* Higher-order functions */ +apply_twice : f x -> f (f x); +double : x -> x * 2; + +/* Using apply_twice */ +result : apply_twice @double 3; +..out result; /* Output: 12 (3*2=6, 6*2=12) */ +``` + +## Debugging and Testing + +### Assertions + +Use assertions to test your code: + +```plaintext +/* Testing your functions */ +double : x -> x * 2; +..assert (double 5) = 10; +..assert (double 0) = 0; +..assert (double (-3)) = -6; + +..out "All tests passed!"; +``` + +### Debug Output + +Add debug output to understand what's happening: + +```plaintext +/* Debugging a function */ +process_data : x -> { + ..out "Processing:"; + ..out x; + result : x * 2; + ..out "Result:"; + ..out result; + result +}; + +final : process_data 5; +..out "Final result:"; +..out final; +``` + +## Best Practices + +### Break Down Complex Operations + +```plaintext +/* Complex operation broken down */ +data : {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + +/* Step 1: Filter */ +is_even : x -> x % 2 = 0; +evens : filter @is_even data; + +/* Step 2: Transform */ +square : x -> x * x; +squared : map @square evens; + +/* Step 3: Aggregate */ +total : reduce @add 0 squared; +..out total; +``` + +### Use Pattern Matching for Conditionals + +```plaintext +/* Good: Pattern matching */ +classify : x -> + when x is + 0 then "zero" + 1 then "one" + _ then "other"; +``` + +### Embrace Immutability + +```plaintext +/* Good: Immutable operations */ +person : {name: "Alice", age: 30}; +updated : t.set person "age" 31; +/* person remains unchanged */ + +/* Avoid: Trying to modify existing data, + this language doesn't support mutation */ +``` + +## Next Steps + +You now have a solid foundation in the scripting language! Here are some areas to explore: + +1. **Advanced Pattern Matching**: Complex patterns and nested matching +2. **Table Comprehensions**: Building tables from other data +3. **Function Composition**: Building complex transformations +4. **Error Handling**: Working with edge cases and invalid data +5. **Performance**: Understanding how the language executes your code + +For a deep dive into combinators and advanced problem-solving patterns, check out the **[Combinators Deep Dive tutorial](Combinators_Deep_Dive.md)**. + +The language is designed to be functional and expressive. As you practice, you'll find that many operations become more natural when you think in terms of data transformations rather than step-by-step instructions. + +Happy coding! \ No newline at end of file |