From 1fe296646ebeb8b6da4b25a0a2b96ee5b6c37ff8 Mon Sep 17 00:00:00 2001 From: Mitsuhiro Nakamura Date: Tue, 6 Jul 2021 21:36:53 +0900 Subject: [PATCH] Update documents for `accumulate` macro --- changelog.md | 1 + reference.md | 22 ++++++++++++++++++++++ src/fennel/macros.fnl | 9 ++++----- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/changelog.md b/changelog.md index 8c322173..f8b8e3aa 100644 --- a/changelog.md +++ b/changelog.md @@ -12,6 +12,7 @@ Backwards-incompatible changes are **marked in bold**. * Make macro tables shadow runtime tables more consistently * Add `,complete foo` repl command * Add `fennel.syntax` function describing built-ins +* Add `accumulate` macro ## 0.9.2 / 2021-05-02 diff --git a/reference.md b/reference.md index b82ffbbd..67f99977 100644 --- a/reference.md +++ b/reference.md @@ -812,6 +812,28 @@ value into a table is a no-op. Like `each` and `for`, the table comprehensions support an `:until` clause for early termination. +### `accumulate` iterator accumulation + +Run through an iterator and performs accumulation, similar to `fold` +and `reduce` commonly used in functional programming languages. +Like `collect` and `icollect`, it takes an iterator binding table +and an expression as its arguments. The difference is that in +`accumulate`, the first two items in the binding table are used as +an "accumulator" variable and its initial value. +For each iteration step, it evaluates the given expression and +the returned value becomes the next accumulator variable. +`accumulate` returns the final value of the accumulator variable. + +Example: + +```fennel +(accumulate [avg 0 + i n (ipairs [1 2 3 4])] + (let [/i (/ i)] + (+ (* avg (- 1 /i)) (* n /i)))) +;; -> 2.5 +``` + ### `values` multi-valued return Returns multiple values from a function. Usually used to signal diff --git a/src/fennel/macros.fnl b/src/fennel/macros.fnl index 174c43c5..facff4f3 100644 --- a/src/fennel/macros.fnl +++ b/src/fennel/macros.fnl @@ -151,14 +151,13 @@ returns (fn accumulate* [iter-tbl accum-expr ...] "Accumulation macro. -Similar to `collect` and `icollect`, it takes a binding table and an -expression as its arguments. +It takes a binding table and an expression as its arguments. In the binding table, the first symbol is bound to the second value, being an -initial accumulating variable. The rest are an iterator binding table in the +initial accumulator variable. The rest are an iterator binding table in the format `each` takes. It runs through the iterator in each step of which the given expression is -evaluated, and its returned value updates the accumulating variable. -It eventually returns the final value of the accumulating variable. +evaluated, and its returned value updates the accumulator variable. +It eventually returns the final value of the accumulator variable. For example, (accumulate [total 0