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
