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.
>>>>
>>>

Reply via email to