On the other hand, I've been dealing with that in the past, and I agree that it would have been very helpful having @OperationRename, at least for prototyping. What I did in the past, was to create an extension for the specific library in order to be able to use operators everywhere in the project's code, not just a part of it, so that's where my bias comes from. I didn't see myself using it contained in small pieces of code but in an entire codebase.
However I guess using @OperationRename, for example in a Groovy script, doing some maths using a third party library (not following Groovy operators conventions), makes perfect sense. Thinking in a bigger project, If I've got it right, if I had a class where I would like to contain all mathematical operations, I could annotate the class with @OperationRename and everything would go ok unless I use different libraries with different method names for the same operator. But then I could extract what I needed in different methods. Sounds reasonable. Bottom line, changed my mind (and of course forget about what I said about @ModXXX annotation) Cheers, Mario El jue, 23 mar 2023 a las 13:28, Paul King (<pa...@asert.com.au>) escribió: > We could go with an AST transform specifically for fixing "mod" but I > don't think it is accurate to say the feature isn't wanted in its own right. > We already do the same kind of rename using runtime metaprogramming all > the time, we would now just have a way to do it using compile-time > metaprogramming as well. > > Some examples which spring to mind: > Groovy's operators: plus, minus, multiply, power > Apache Commons Math matrices: add, subtract, multiply, power > EJML matrices: plus, minus, mult, n/a > Nd4j matrices: add, sub, mmul, n/a > ojAlgo matrices: add, subtract, multiply, power > Commons numbers fractions: add, subtract, multiply, pow > Commons numbers complex: add, subtract, multiply, pow > > Cheers, Paul. > > > On Thu, Mar 23, 2023 at 6:21 PM Mario Garcia <mario.g...@gmail.com> wrote: > >> The idea of fixing inconsistencies is great. I also like the idea of >> giving a mid-term solution for those using the mod operator "incorrectly". >> But I'm not sure about opening the door for precisely overloading operators >> with different names than the ones specified by default, that seems to be >> just the opposite this proposal is for, to avoid different people to >> approach the same operator differently. Apart from that, I think that the >> new feature has to be maintained as well, and it wasn't born as a feature >> Groovy developers wanted but a workaround for something that had to be >> fixed. >> >> I would add the @OperationRename renaming it as @ModRenamed (or something >> alike) as a transitional workaround for those using mod the old way. >> >> My two cents >> Mario >> >> El jue, 23 mar 2023 a las 2:44, Paul King (<pa...@asert.com.au>) >> escribió: >> >>> Hi folks, >>> >>> It has been a while but I finally got back around to this issue. >>> >>> As a reminder, this issue is about using "mod" as the name of the method >>> for the "%" operator. Both remainder and mod are the same for positive >>> numbers, and we are guilty in informal contexts of sometimes conflating the >>> names, but they differ for negative numbers. This caused a difference (only >>> for negative numbers) for BigIntegers. In the earlier email, I was going to >>> look at "patches" which would allow us to keep "mod" as the operator name. >>> I tried numerous "fixes" but they all seemed like patches on top of patches >>> rather than a clean solution. So, instead I went with the solution (which I >>> previously described as "somewhat intrusive") of renaming the name of the >>> operator method to "remainder". This makes it a breaking change for Groovy >>> 5 (for -ve numbers and also anyone using the "mod" method name relying on >>> DSL-like code) but arrives at a much cleaner solution. >>> >>> I have created the following PR here: >>> >>> https://github.com/apache/groovy/pull/1878 >>> >>> To minimise the impact on existing users, I added a new AST >>> transform, @OperationRename, which could be used by anyone affected by the >>> change when writing DSL-like code using "mod". This also has the advantage >>> of giving another option when wanting to use operator overloading with >>> existing libraries that might not use the method names Groovy uses, e.g. >>> subtract/add/times instead of minus/plus/multiply. We could also look at >>> some metaclass tweaking so that the runtime looks for "mod" as a fallback >>> for "remainder" before jumping to method missing but I'd probably do that >>> as a second pass only if there is sufficient interest. >>> >>> Thoughts? >>> >>> Cheers, Paul. >>> >>> >>> On Fri, Oct 28, 2022 at 9:34 PM Paul King <pa...@asert.com.au> wrote: >>> >>>> Hi folks, >>>> >>>> As part of fixing GROOVY-10800, I was planning to make the behavior >>>> for the "%" operator for BigInteger be consistent with our other data >>>> types (and with Java). >>>> >>>> Basically, there is a distinction between "remainder" and "modulo" for >>>> negative numbers. >>>> For the expression "numerator op divisor", they will be the same for >>>> positive numbers but for negative numbers, "remainder" will return a >>>> negative number for a negative numerator while "modulo" will always >>>> return a number "0 <= result < divisor". You can get one from the >>>> other by adding the divisor to a negative result from "remainder". >>>> >>>> What is sometimes a little confusing is that the "remainder" operator >>>> (%) is often informally referred to as the "mod" operator (since they >>>> are the same for positives). Indeed, we use "mod" as the name of the >>>> method to use for operator overloading purposes. >>>> >>>> Currently the behavior is: >>>> >>>> def nums = [-10, -10L, -10f, -10d, -10G, -10.0G] >>>> assert nums.collect{ it % 3 } == [-1, -1, -1f, -1d, 2G, -1.0G] >>>> >>>> (Note: The BigDecimal result relies on GROOVY-10786, so currently only >>>> in master.) >>>> >>>> Changing the behavior is easy (albeit breaking for negatives) but >>>> there is a knock on consequence. Since we use "mod" as our method for >>>> operator overloading, the BigInteger "mod" method is then no longer >>>> available. >>>> >>>> For Groovy 5, we could go and rename our operator overloading method >>>> from "mod" to "remainder" or some such but it is quite an intrusive >>>> change. >>>> >>>> There is a workaround which we could document: >>>> >>>> def negTen = -10G >>>> assert 2G == negTen.modPow(1, 3) >>>> >>>> And/or we could provide a "modulo" extension method on BigInteger to >>>> allow: >>>> >>>> assert 2G == negTen.modulo(3) >>>> >>>> This last approach was what I was thinking of doing. >>>> >>>> Thoughts? >>>> >>>> Cheers, Paul. >>>> >>>