diff options
Diffstat (limited to 'docs/reductions.md')
| -rw-r--r-- | docs/reductions.md | 81 |
1 files changed, 35 insertions, 46 deletions
diff --git a/docs/reductions.md b/docs/reductions.md index 143a59ad..b4e78624 100644 --- a/docs/reductions.md +++ b/docs/reductions.md @@ -1,14 +1,35 @@ # Reductions In Tomo, reductions are a way to express the idea of folding or reducing a -collection of values down to a single value. Reductions use an infix operator -surrounded by parentheses, followed by a collection: +collection of values down to a single value. Reductions use a parenthesized +infix operator followed by a colon, followed by a collection: ```tomo nums := [10, 20, 30] -sum := (+) nums +sum := (+: nums) >> sum -= 60 += 60? +``` + +Reductions return an optional value which will be a null value if the thing +being iterated over has no values. In such cases, the reduction is undefined. +As with all optionals, you can use either the postfix `!` operator to perform +a runtime check and error if there's a null value, or you can use `or` to +provide a fallback value: + +```tomo +nums := [:Int] +sum := (+: nums) + +>> sum += !Int + +>> sum or 0 += 0 + +>> nums = [10, 20] +>> (+: nums)! += 30 ``` Reductions can be used as an alternative to generic functions like `sum()`, @@ -17,19 +38,19 @@ Reductions can be used as an alternative to generic functions like `sum()`, ```tomo # Sum: ->> (+) [10, 20, 30] +>> (+: [10, 20, 30])! = 60 # Product: ->> (*) [2, 3, 4] +>> (*: [2, 3, 4])! = 24 # Any: ->> (or) [no, yes, no] +>> (or: [no, yes, no])! = yes # All: ->> (and) [no, yes, no] +>> (and: [no, yes, no])! = no ``` @@ -40,11 +61,11 @@ a collection using the `_min_` and `_max_` infix operators. ```tomo # Get the maximum value: ->> (_max_) [10, 30, 20] +>> (_max_: [10, 30, 20])! = 30 # Get the minimum value: ->> (_min_) [10, 30, 20] +>> (_min_: [10, 30, 20])! = 10 ``` @@ -55,11 +76,11 @@ maximum value _according to some feature_. ```tomo # Get the longest text: ->> (_max_.length) ["z", "aaaaa", "mmm"] +>> (_max_.length: ["z", "aaaaa", "mmm"])! = "aaaaa" # Get the number with the biggest absolute value: ->> (_max_:abs()) [1, -2, 3, -4] +>> (_max_:abs(): [1, -2, 3, -4])! = -4 ``` @@ -71,42 +92,10 @@ while filtering out values or while applying a transformation: ```tomo # Sum the lengths of these texts: ->> (+) t.length for t in ["a", "bc", "def"] +>> (+: t.length for t in ["a", "bc", "def"])! = 6 # Sum the primes between 1-100: ->> (+) i for i in 100 if i:is_prime() +>> (+: i for i in 100 if i:is_prime())! = 1060 ``` - -## Empty Collection Behavior - -If a collection has no members, the default behavior for a reduction is to -create a runtime error and halt the program with an informative error message. -If you instead want to provide a default fallback value, you can use `else:` to -give one: - -```tomo -empty := [:Int] ->> (+) empty else: -1 -= -1 - ->> (+) empty -# Error: empty iterable! -``` - -You can also provide your own call to `fail()` or `exit()` with a custom error -message, or a short-circuiting control flow statement (`return`, `stop`, -`skip`) like this: - -```tomo ->> (_max_) things else: exit("No things!") - -for nums in num_arrays: - product := (*) nums else: skip - do_thing(product) - -func remove_best(things:[Thing]): - best := (_max_.score) things else: return - best:remove() -``` |
