Re: features for groovy-6.0.0-alpha-1

MG <mgbiz-yvYIh6MZAuFWk0Htik3J/[email protected]> Thu, 30 Apr 2026 19:14:03 +0200
Newsgroups gmane.comp.lang.groovy.devel
Message-ID <[email protected]>
Hi Paul,

 1. I am a bit worried about the dual use of literal map syntax and
    object decomposition in Groovy:
     1. In the "def sum(xs) ..." example xs is list (of Number|s), and
        "case []" is the branch that handles an empty list.
     2. Whereas in the "switch (event) ..." example the " case [type:
        'click', ...]" branch does not compare to a map, but
        decompositions the event object into its type, etc parts.
     3. While seeing any object in Groovy as a map of properties has
        been around forever,  it does already clash with peoples'
        expectations sometimes when the object /is /a Map (violating
        least surprise).
     4. So I was wondering if introducing a seperate syntax for object
        decomposition which sets it apart from literal map syntax would
        make sense... ?
 2. In "case [type: 'click',  x: var x, y: var y]" the "x: var x" parts
    looks unnecsessarily verbose/Java-ish to me - can/should we allow
    just "x" here, i.e. "case [ type: 'click',  x, y ] -> handleClick(x, y)"
     1. Or, in case a mapping shall occur, can we drop the "var",
        i.e. "case [ type: 'click', widthPos:x, heightPos:y ] ->
        handleClick(x, y)"
         1. (This might tie in with my suggestion above: This might
            only work if there is an explicit syntax for a decomposition
            pattern that does not  look like a map literal.)

Cheers,
mg

def sum(xs) {
         switch (xs) {
             case []                -> 0
             case [var h, var... t] -> h + sum(t)
         }
     }

  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()
     }



Am 27.04.2026 um 13:39 schrieb Paul King:
> 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.