Good day folks,

I hope everyone is doing very well. This is my very first ever email to a 
development mailing list ever, so apologies in advance if I have broken any 
rules or etiquette (I am used to the GitHub style flavor of contributing to 
projects). I certainly didn’t intend to. I just hope I can help out and might 
be a little overly enthusiastic.

Quickly, I have been programming for a while now (over 15 years) and just 
recently stumbled onto Groovy for reasons that are amusing to say the least. 
Anyways, I have been using the Groovy programming language for a little bit now 
(around 3 months) as well as starting to maintain my own compilation of it (as 
you will soon see why).

I have been making a number of observations around things that could be fixed, 
improved, are missing, or bugs/little odds-and-ends in the documentation that 
are incorrect/inaccurate. All of which I figured that I could help fix, 
clean-up, and enhance.

According to the ASF contribution page it says that the Jira instance is used 
for tracking tickets and contributing. However, visiting the Jira link, the 
ability to get an account is disabled. I am hoping someone on this list could 
help if that is the appropriate way to do things. If not, I would greatly 
appreciate being pointed in the right direction instead as well as, again, 
offer my apologies for misunderstanding.

Giant list of annoyingly pedantic details about docs/improvements coming up … 
feel free to stop reading now.

Any who, for those interested, some of the items I have made a note of are (in 
relatively no particular order) when doing some stuff with the Groovy 5.0.6 
tag/branch:

- The `param` method with the overload taking 3 parameters in 
`src/main/java/org/codehaus/groovy/ast/tools/GeneralUtils.java` (i.e. `public 
static Parameter param(final ClassNode type, final String name, final 
Expression initialExpression)`) could be simplified to just `return new 
Parameter(type, name, initialExpression);` since internally the respective 
constructor `Parameter` invokes `setInitialExpression` which, if provided a 
null value, will result in the exact same object as if it was not invoked 
anyway. Perhaps there is a reason the null check is needed in the utility 
method but I removed it in my build, ran tests, and built my own projects 
(which heavily use it) and everything passed/worked great.
- The `cloneParams` method in 
`src/main/java/org/codehaus/groovy/ast/tools/GeneralUtils.java` could be 
refactored to provide the default value expression of each iterated parameter 
to the `param` method (e.g. `param(p.getOriginType(), p.getName(), 
p.getDefaultValue())`).
- Furthermore, the same `cloneParams` method could be enhanced to do a full, 
proper clone (even deeply) of the parameters by cloning each iterated 
parameter’s modifiers, staticContext state, closuredSharedVariable state, as 
well as any and all annotation nodes associated with each parameter, etc.
- The `ArrayGroovyMethods` could have `isEmpty` methods provided as extension 
methods so that anyone using either array or proper `Collection`/`Iterable` 
instances can have a pseudo-unified interface, further blurring the lines 
between primitive arrays and the Collections API’s objects. This is a personal 
favorite of mine and something I just implemented in my compilation yesterday.
- Add a copy constructor (and implement `Cloneable`) on `MethodNode` so that 
someone writing an AST transformation can more easily manipulate a class node 
to add more methods (for example the `@Delegate` annotation or another one of 
several AST transformations I am writing for my own projects). Ideally, I’d 
take this further and implement copy constructors and `Cloneable` for all 
`ASTNode` types, and if possible `Statement` types and `Expression` types. I 
often find myself wanting quick, easy, clean, clear, and correct ways to clone 
those objects when I am doing compile time meta-programming stuff.
- The `findResult` API documentation in/on 
https://docs.groovy-lang.org/docs/latest/html/groovy-jdk/java/lang/Iterable.html#findResult(java.lang.Object)
 is duplicated between overloads in the summary table at the top. The detailed 
method documentation for `findResult(Object)` is a duplicate of the 
`findResult(Object, Closure)` overload too.
- The `@Log` API documentation in/on 
https://docs.groovy-lang.org/3.0.2/html/gapi/groovy/util/logging/Log.html 
generated AST example is missing a parenthesis for the end of `if` statement 
which is hyper pedantic, I know and I apologize. That’s my personality. 
However, it might be confusing to beginners or people who might think it’s an 
optional parenthesis (I don’t believe it is) or that somehow a closure is 
involved here (it isn’t).
- In the “Methods inherited from” header links in/for the various Collection 
style API docs, it links to the Oracle JavaDocs (Java SE 8/11 no less) which 
may not necessarily be the most useful for someone exploring Groovy 
documentation. I would imagine someone exploring the docs would expect to be 
linked to the Groovy documentation for the enhancements to those API’s (or at 
least have the Oracle JavaDocs as a clearly denoted separate link).
- In the `with` & `tap` style explanation documentation in/on 
https://docs.groovy-lang.org/docs/latest/html/documentation/style-guide.html#_using_with_and_tap_for_repeated_operations_on_the_same_bean,
 I believe that the last two code blocks for that section are swapped based on 
the sentence leading up to them “To use this as a builder, that just returns 
the incoming object, there is also tap(): …” which then shows `with` being used 
instead. And I might just be out-of-the-loop, but I still don’t know what is 
meant by the ending note there of that section: "Note: you can also use 
with(true) instead of tap() and with(false) instead of with().” … I am still 
very confused about what this means, why it would be helpful, when it would be 
useful, or what it is even doing. I would like to know … really.
- Link to the slide deck Paul King used/provided in his talk in 2014 at 
SpringOne Dallas around how to write AST transformations (it’s an excellent 
quick-reference resource): 
[groovy258-ast-compile-time-metaprogramming-workshop/slides/groovyy-ast-slides.pdf
 at master · mtumilowicz/groovy258-ast-compile-time-metaprogramming-workshop · 
GitHub](https://github.com/mtumilowicz/groovy258-ast-compile-time-metaprogramming-workshop/blob/master/slides/groovyy-ast-slides.pdf)

Furthermore, some more interesting ideas I have implemented are allowing 
implicitly inferred method pointers/references to statically imported methods 
(e.g. `import static com.example.fancy.MyCalculator.*; [1, 2, 
3].collect(.&my_static_multiplier); [1, 2, 
3].collect(::my_static_multiplier)`). Crazy I am sure, but I was doing sillier 
things like an AST transformation to inject a class with static fields with the 
same names as all static methods except prefixed with `__`. Extending Groovy’s 
language syntax to allow this was the first step for me in building Groovy from 
source.

Anywho, I have written a long enough wall of text (sorry, it’s a personality 
quirk). I am glad to join the mailing list and hope to learn a ton more, help 
out, and give back to the community.

Again, my sincere apologies if I have missed something or not gotten mailing 
list development quite right.

Please let me know if there is anything I can do to help out as well as any 
feedback for me from this first email. Looking forward to being a part of the 
community.

Thanks,
Matt

Reply via email to