Re: features for groovy-6.0.0-alpha-1
Jochen Theodorou <[email protected]> Thu, 30 Apr 2026 17:36:21 +0200
| Newsgroups | gmane.comp.lang.groovy.devel |
|---|---|
| Message-ID | <[email protected]> |
actually one question regarding GPars features.
Afaik you could do urls.collectParallel{...}, but also
urls.parallel.collect{...}.
I guess it was excluded because of getParallel() as "Legacy JSR-166
ParallelArray API; obsolete since Java 8 streams"
But I see this more as a DSL choice, then depending on a feature. I
personally like urls.parallel().collect most, then urls.parallel.collect
and only on last place urls.collectParallel. Frankly I would have even
expected urls.parallelCollect, if I had seen it for the first time.
To be more specific.. assume you have
def findOkUrls(urls) {
urls.collect { fetch(it) }
.findAll { it.status == 200 }
.groupBy { it.host }
}
findOkUrls(myUrls)
and then you could replace that with
def findOkUrls(urls) {
urls.collect { fetch(it) }
.findAll { it.status == 200 }
.groupBy { it.host }
}
ParallelScope.withPool(Pool.cpu()) {
findOkUrls(myUrls)
}
Meaning not touching the method itself.
bye Jochen
On 4/30/26 05:37, Paul King wrote:
> I have merged the GPars-related functionality. I'll tidy the docs but
> shout if you spot any problems.
>
> Cheers, Paul.
>
> On Mon, Apr 27, 2026 at 9:39 PM Paul King <[email protected]
> <mailto:[email protected]>> wrote:
>
> Hi folks,
>
> I believe the following features are ready for inclusion in Groovy
> 6.0.0-alpha-1.
> Please see the relevant PRs and Jira issues for more information.
>
> Feedback, as always, is welcome.
>
> Cheers, Paul.
>
> GEP-18 -- Ported GPars features
> ================================
>
> 1. Parallel collections inside a scope -- drop-in speedup
>
> ParallelScope.withPool(Pool.cpu()) {
> urls.collectParallel { fetch(it) }
> .findAllParallel { it.status == 200 }
> .groupByParallel { it.host }
> }
>
> Familiar GPars xxxParallel names, pool-isolated and
> virtual-thread-ready.
>
> 2. Dataflows -- orchestration by data dependency, not thread
> choreography
>
> def df = new Dataflows()
> async { df.result = combine(df.user, df.prefs) }
> async { df.user = loadUser(id) }
> async { df.prefs = loadPrefs(id) }
> println await(df.result)
>
> The order in source is irrelevant; readers block until the
> writers bind. Reads as plainly as sequential code.
>
> But also, actors/active objects, agents and channels.
>
> GEP-20 -- Additional multi-assignment forms
> ============================================
>
> 1. Tail rest against a Stream -- head/body split with no
> materialisation
>
> Files.lines(path).withCloseable { src ->
> def (header, *body) = src
> body.filter { !it.isBlank() }.forEach { process(it) }
> }
>
> Path A keeps the Stream lazy and propagates onClose -- the
> killer demo for the streaming contract.
>
> 2. Head and middle rest -- edge-aware slicing in one line
>
> def (first, *middle, last) = readings // peel both ends
> def (l, *m, r) = segment // boundary + interior
>
> Replaces [0] / [1..-2] / [-1] boilerplate that's surprisingly
> common.
>
> 3. Map-style destructuring -- beans and config in one shot
>
> def (host: h, port: p, name: n) = config
> def (name: String fullName, age: int a) = person
>
> Works against Map, beans, and GroovyObject uniformly via the
> MOP -- the rename form (name: fullName) is a quiet bonus.
>
>
> When assessing GEP-20, bear in mind the very early draft for GEP-19
> targetted tentatively for Groovy 7.
>
> GEP-19 -- Structural pattern matching in switch
> ================================================
>
> 1. Recursive list algorithm in its canonical functional shape
>
> def sum(xs) {
> switch (xs) {
> case [] -> 0
> case [var h, var... t] -> h + sum(t)
> }
> }
>
> The motivating example -- what you can't write tidily today.
>
> 2. Map patterns for tagged-shape dispatch (events, JSON, configs)
>
> switch (event) {
> case [type: 'click', x: var x, y: var y] -> handleClick(x, y)
> case [type: 'key', code: var k] -> handleKey(k)
> case [type: 'scroll', ...] -> redraw()
> }
>
> Open semantics plus rest binding makes this read like a
> protocol spec.
>
> 3. Type pattern + record pattern + guard -- visitor replacement
>
> switch (shape) {
> case Circle c when c.radius > 0 -> Math.PI * c.radius**2
> case Rect(int w, int h) -> w * h
> case Line(_, Point p2) -> "ends at $p2"
> default -> 0
> }
>
> One construct subsumes instanceof chains, accessor calls, and
> the constraint check.
>