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&lt;String, Integer&gt; merge(Map&lt;String, Integer&gt; a, 
Map&lt;String, Integer&gt; b) {
         var out = new LinkedHashMap(a)
         b.each { k, v -&gt; out.merge(k, v) { x, y -&gt; 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 &gt;= 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.&amp;add) == 5050
     assert ['a', 'b', 'c'].sumParallel(Concat.&amp;join) == 'abc'
+    assert [3, 1, 4, 1, 5, 9, 2, 6].sumParallel(Largest.&amp;max) == 9
 
     // REJECTED at compile time — subtraction is not associative:
     // [1, 2, 3].injectParallel(0) { a, b -&gt; 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 &lt;&lt; "+$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&#8217;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&trade; 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&trade; Learn 
Documentation Download Support Contribute Ecos [...]
         "url": "blog/groovy6-functional.html",
         "site": "dev"
     },

Reply via email to