diff --git a/examples/LocalDispatch/README.md b/examples/LocalDispatch/README.md new file mode 100644 index 00000000..2022306f --- /dev/null +++ b/examples/LocalDispatch/README.md @@ -0,0 +1,74 @@ +# Local Dispatch with Arrow Operator + +This example demonstrates the `->` arrow operator for local dispatch, which replaces the pizza operator `|>` from old Roc. + +## Overview + +In new Roc, there are two ways to chain function calls: + +1. **Method syntax** (`.method()`) - for methods defined on a type +2. **Local dispatch** (`->function`) - for functions in local scope + +## The Arrow Operator + +The `->` operator passes the left-hand value as the first argument to the function on the right: + +```roc +# These are equivalent: +double(5) +5->double + +# Chain multiple calls (reads left-to-right): +3->double->add_ten->square +# Same as: square(add_ten(double(3))) +``` + +## Defining Helper Functions + +```roc +double : I64 -> I64 +double = |n| n * 2 + +add_ten : I64 -> I64 +add_ten = |n| n + 10 + +square : I64 -> I64 +square = |n| n * n +``` + +## Mixing Method Syntax and Local Dispatch + +You can combine both styles in a single expression: + +```roc +wrap_parens : Str -> Str +wrap_parens = |s| "(${s})" + +format_number : I64 -> Str +format_number = |n| + n.to_str()->wrap_parens # method, then local dispatch +``` + +## Output + +Run this from the directory that has `main.roc` in it: + +``` +$ roc main.roc +5->double = 10 +3->double->add_ten->square = 256 +chain_math(2) = 196 +42->format_number = (42) + +Style comparison: + square(add_ten(double(7))) = 576 + 7->double->add_ten->square = 576 +``` + +## When to Use Each Style + +| Style | Syntax | Use When | +|-------|--------|----------| +| Method syntax | `value.method()` | Calling methods defined on the type | +| Local dispatch | `value->function` | Calling local functions for left-to-right chaining | +| Traditional | `function(value)` | Simple single calls or when nesting is clear | diff --git a/examples/LocalDispatch/main.roc b/examples/LocalDispatch/main.roc new file mode 100644 index 00000000..fa3c5816 --- /dev/null +++ b/examples/LocalDispatch/main.roc @@ -0,0 +1,72 @@ +app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.19.0/Hj-J_zxz7V9YurCSTFcFdu6cQJie4guzsPMUi5kBYUk.tar.br" } + +import pf.Stdout + +# Local Dispatch Example +# ====================== +# The `->` operator passes the left-hand value as the first argument +# to a function in local scope. This replaces the pizza operator `|>` +# for functions that aren't methods on the type. + +# Define some helper functions +double : I64 -> I64 +double = |n| n * 2 + +add_ten : I64 -> I64 +add_ten = |n| n + 10 + +square : I64 -> I64 +square = |n| n * n + +# String helper +wrap_parens : Str -> Str +wrap_parens = |s| "(${s})" + +# You can chain local dispatch calls +chain_math : I64 -> I64 +chain_math = |n| + n->double->add_ten->square + +# Mix method syntax and local dispatch +format_number : I64 -> Str +format_number = |n| + n.to_str()->wrap_parens + +main! : List(Str) => Try({}, [Exit(I32)]) +main! = |_args| { + # Basic local dispatch: value->function + # This is equivalent to: double(5) + result1 = 5->double + Stdout.line!("5->double = ${result1.to_str()}") + + # Chain multiple local dispatch calls + # This is equivalent to: square(add_ten(double(3))) + result2 = 3->double->add_ten->square + Stdout.line!("3->double->add_ten->square = ${result2.to_str()}") + + # Using the helper function + result3 = chain_math(2) + Stdout.line!("chain_math(2) = ${result3.to_str()}") + + # Mix method syntax (.method) with local dispatch (->func) + # Method syntax: calls a method defined on the type + # Local dispatch: calls a function in local scope + formatted = 42->format_number + Stdout.line!("42->format_number = ${formatted}") + + # Compare the styles: + Stdout.line!("") + Stdout.line!("Style comparison:") + + # Traditional function call (nested, reads inside-out) + traditional = square(add_ten(double(7))) + Stdout.line!(" square(add_ten(double(7))) = ${traditional.to_str()}") + + # Local dispatch (chained, reads left-to-right) + arrow_style = 7->double->add_ten->square + Stdout.line!(" 7->double->add_ten->square = ${arrow_style.to_str()}") + + # Both produce the same result! + + Ok({}) +}