This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a commit to branch asf-site
in repository https://gitbox.apache.org/repos/asf/groovy-dev-site.git
The following commit(s) were added to refs/heads/asf-site by this push:
new 7e63852 2026/05/20 11:15:21: Generated dev website from
groovy-website@c29021a
7e63852 is described below
commit 7e63852a0e23e30d4b7f03bbdf29106e257350c0
Author: jenkins <[email protected]>
AuthorDate: Wed May 20 11:15:21 2026 +0000
2026/05/20 11:15:21: Generated dev website from groovy-website@c29021a
---
blog/groovy6-functional.html | 34 +++++++++++++++++++++++++---------
search/search-index.json | 2 +-
2 files changed, 26 insertions(+), 10 deletions(-)
diff --git a/blog/groovy6-functional.html b/blog/groovy6-functional.html
index bc10e40..614a0a3 100644
--- a/blog/groovy6-functional.html
+++ b/blog/groovy6-functional.html
@@ -205,17 +205,17 @@ In Groovy 6 the algebra moves <em>onto the
method</em>:</p>
import groovy.transform.Reducer
class Sum {
- @Associative @Reducer(zero = '0')
+ @Reducer(zero = '0')
static int add(int a, int b) { a + b }
}
class Concat {
- @Associative @Reducer(zero = '""')
+ @Reducer(zero = '""')
static String join(String a, String b) { a + b }
}
class Tally {
- @Associative @Reducer(zero = '[:]')
+ @Reducer(zero = '[:]')
static Map<String, Integer> merge(Map<String, Integer> a,
Map<String, Integer> b) {
var out = new LinkedHashMap(a)
b.each { k, v -> out.merge(k, v) { x, y -> x + y } }
@@ -225,6 +225,20 @@ class Tally {
</div>
</div>
<div class="paragraph">
+<p><code>@Reducer</code> is the monoid form: associative plus a named
identity. Use
+<code>@Associative</code> alone when the operation is associative but has no
+natural identity in the problem domain — a semigroup, usable with
+unseeded reductions only:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="prettyprint highlight"><code data-lang="groovy">class Largest {
+ @Associative
+ static int max(int a, int b) { a >= b ? a : b }
+}</code></pre>
+</div>
+</div>
+<div class="paragraph">
<p>The point is not the annotations. The point is the type-checking
extension behind them:</p>
</div>
@@ -234,6 +248,7 @@ extension behind them:</p>
def reductions() {
assert (1..100).toList().injectParallel(0, Sum.&add) == 5050
assert ['a', 'b', 'c'].sumParallel(Concat.&join) == 'abc'
+ assert [3, 1, 4, 1, 5, 9, 2, 6].sumParallel(Largest.&max) == 9
// REJECTED at compile time — subtraction is not associative:
// [1, 2, 3].injectParallel(0) { a, b -> a - b }
@@ -271,7 +286,7 @@ declarations, no lift / unlift:</p>
</div>
<div class="listingblock">
<div class="content">
-<pre class="prettyprint highlight"><code
data-lang="groovy">@TypeChecked(extensions =
['groovy.typecheckers.PurityChecker',
+<pre class="prettyprint highlight"><code
data-lang="groovy">@TypeChecked(extensions =
['groovy.typecheckers.PurityChecker(allows: "LOGGING")',
'groovy.typecheckers.ModifiesChecker'])
class Calculator {
BigDecimal total = 0
@@ -290,7 +305,7 @@ class Calculator {
ledger << "+$amount"
}
- @Pure(allows = Pure.Effect.LOGGING)
+ @Pure
BigDecimal balance() {
log.fine "balance read"
total
@@ -319,10 +334,11 @@ state-transition function — pre- and post-conditions,
with `old.</code>
referring to pre-state.</p>
</li>
<li>
-<p><code>balance</code> is pure <em>modulo logging</em>. The
<code>allows</code> set is a small
-effect lattice (<code>LOGGING</code>, <code>METRICS</code>, <code>IO</code>,
<code>NONDETERMINISM</code>) —
-graded effects, in the cats-effect sense, but the verification work
-is in the checker rather than the type.</p>
+<p><code>balance</code> is pure <em>modulo logging</em>. The checker’s
<code>allows</code> option
+declares a small effect lattice (<code>LOGGING</code>, <code>METRICS</code>,
<code>IO</code>,
+<code>NONDETERMINISM</code>) and tolerates calls in those categories from any
+<code>@Pure</code> method in scope — graded effects, in the cats-effect sense,
+but the verification work is in the checker rather than the type.</p>
</li>
</ul>
</div>
diff --git a/search/search-index.json b/search/search-index.json
index aa67636..fdb7d5c 100644
--- a/search/search-index.json
+++ b/search/search-index.json
@@ -240,7 +240,7 @@
{
"id": "blog/groovy6-functional.html",
"title": "The Apache Groovy programming language - Blogs - Groovy 6
features for Functional Programmers",
- "content": "The Apache Groovy programming language - Blogs - Groovy 6
features for Functional Programmers Socialize Discuss on the mailing list
Groovy on X Groovy on Bluesky Groovy on Mastodon Groovy on LinkedIn Events and
conferences Source code on GitHub Report issues in Jira Stack Overflow
questions Slack Community You are using an outdated browser. Please upgrade
your browser to improve your experience. Apache Groovy™ Learn
Documentation Download Support Contribute Ecos [...]
+ "content": "The Apache Groovy programming language - Blogs - Groovy 6
features for Functional Programmers Socialize Discuss on the mailing list
Groovy on X Groovy on Bluesky Groovy on Mastodon Groovy on LinkedIn Events and
conferences Source code on GitHub Report issues in Jira Stack Overflow
questions Slack Community You are using an outdated browser. Please upgrade
your browser to improve your experience. Apache Groovy™ Learn
Documentation Download Support Contribute Ecos [...]
"url": "blog/groovy6-functional.html",
"site": "dev"
},