As for tersity, I presume the actual usage would look like „foo as Map“ or „foo as List“ anyway, which is actually one less keypress :), and — which in my personal opinion is considerably more important — it offers better consistency and polymorphism.
(I know next to nothing of Intellisense, but I guess it should offer the as operator with a selection of known types, should it not?) Still I might be missing something of importance, of course. All the best, OC > On 2 Nov 2021, at 19:17, MG <mg...@arscreat.com> wrote: > > Hmmm, yes, that would be an option. > More terse & can be discovered via Intellisense are two reasons I could think > of that speak for the toList()/toMap() approach... > > Cheers, > mg > > On 02/11/2021 12:48, OCsite wrote: >> Hi there, >> >> I am probably missing something obvious here, but why adding separate >> methods for this instead of simply reusing asType? >> >> Thanks and all the best, >> OC >> >>> On 2. 11. 2021, at 8:35, Paul King <pa...@asert.com.au> wrote: >>> >>> Thanks for the feedback! I added "toMap()" to the PR. >>> >>> On Tue, Nov 2, 2021 at 7:02 AM MG <mg...@arscreat.com> wrote: >>>> Hi Paul, >>>> >>>> quick "from the top of my head" reply: >>>> >>>> copyWith(...): Sounds like a great idea, I have record-like classes in >>>> use, and the need for something like this arises immediately in practice >>>> getAt(int): Don't see why not, might be useful >>>> toList(): Destructuring should show its strength when pattern matching is >>>> introduced - outside of pattern matching right now I don't see much >>>> application/need for such functionality (but would be interested to see >>>> some practical examples :-) ), but having it does not seem to hurt. >>>> components(): Same as getAt; the name seems quite long, maybe we can come >>>> up with something more terse ? >>>> toMap(): If we have toList(), would a toMap() make sense, so that the map >>>> could be modified and passed as a record ctor argument to create a new >>>> record ? >>>> >>>> Cheers, >>>> mg >>>> >>>> >>>> On 01/11/2021 16:14, Paul King wrote: >>>> >>>> Hi folks, >>>> >>>> I will be ready for a new Groovy 4 release shortly. I am interested in >>>> folks' thoughts on records as they have gone through a few changes >>>> recently (documented in [1], [2] and [3]) and there is a proposal[4] >>>> for a few more enhancements. >>>> >>>> There is a "copyWith" method (still undergoing some refactoring) >>>> similar to the copy method in Scala and Kotlin which allows one record >>>> to be defined in terms of another. It can be disabled if you really >>>> must have Java-like records. The refactoring of that method hit a >>>> slight glitch, so might not work if you grab the latest source but >>>> should be fixed shortly. >>>> >>>> record Fruit(String name, double price) {} >>>> def apple = new Fruit('Apple', 11.6) >>>> assert apply.toString() == 'Fruit[name=Apple, price=11.6]' >>>> def orange = apple.copyWith(name: 'Orange') >>>> assert orange.toString() == 'Fruit[name=Orange, price=11.6]' >>>> >>>> There is a "getAt(int)" method to return e.g. the first component with >>>> myRecord[0] following similar Groovy conventions for other aggregates. >>>> This is mostly targeted at dynamic Groovy as it conveys no typing >>>> information. Similarly, there is a "toList" (current name but >>>> suggestions welcome) method which returns a Tuple (which is also a >>>> list) to return all of the components (again with typing information). >>>> >>>> record Point(int x, int y, String color) {} >>>> def p = new Point(100, 200, 'green') >>>> assert p[0] == 100 >>>> assert p[1] == 200 >>>> assert p[2] == 'green' >>>> def (x, y, c) = p.toList() >>>> assert x == 100 >>>> assert y == 200 >>>> assert c == 'green' >>>> >>>> There is also an optional (turned on by an annotation attribute) >>>> "components" method which returns all components as a typed tuple, >>>> e.g. Tuple1, Tuple2, etc. This is useful for Groovy's static nature >>>> and is automatically handled by current destructuring (see the tests >>>> in the PR). The limitation is that we currently only go to Tuple16 >>>> with our tuple types - which is why I made it disabled by default. >>>> >>>> @RecordBase(componentTuple=true) >>>> record Point(int x, int y, String color) { } >>>> >>>> @TypeChecked >>>> def method() { >>>> def p1 = new Point(100, 200, 'green') >>>> def (int x1, int y1, String c1) = p1.components() >>>> assert x1 == 100 >>>> assert y1 == 200 >>>> assert c1 == 'green' >>>> >>>> def p2 = new Point(10, 20, 'blue') >>>> def (x2, y2, c2) = p2.components() >>>> assert x2 * 10 == 100 >>>> assert y2 ** 2 == 400 >>>> assert c2.toUpperCase() == 'BLUE' >>>> } >>>> >>>> An alternative would be to follow Kotlin's approach and just have >>>> typed methods like "component1", "component2", etc. We might want to >>>> follow that convention or we might want to follow our TupleN naming, >>>> e.g. "getV1", "getV2", etc. We would need to augment the Groovy >>>> runtime and type checker to know about records if we wanted to support >>>> destructuring but we could avoid the "toList" method and "components" >>>> method with its size limitation if we did add such support. >>>> >>>> Any feedback welcome, >>>> >>>> Cheers, Paul. >>>> P.S. Records are an incubating feature - hence may change in backwards >>>> incompatible ways, particularly until we hit Groovy 4 final. >>>> >>>> [1] https://github.com/apache/groovy/blob/master/src/spec/doc/_records.adoc >>>> [2] >>>> https://github.com/apache/groovy/blob/master/src/spec/test/RecordSpecificationTest.groovy >>>> [3] >>>> https://github.com/apache/groovy-website/blob/asf-site/site/src/site/wiki/GEP-14.adoc >>>> [4] https://issues.apache.org/jira/browse/GROOVY-10338 >>>> >>>> >