paulk-asert commented on PR #2958:
URL: https://github.com/apache/groovy/pull/2958#issuecomment-6068869632

   AI read:
   
   > **Why not adjust `PRIMITIVE_DISTANCE_TABLE`?** Distances are summed over 
all arguments, and every integral argument leans 2 points towards `float` 
(`int`?`float` is 5, `int`?`double` is 7). With `n` integral arguments plus one 
`BigDecimal`, the totals are:
   > 
   > - `float`: `5n + x`, where `x` is the table value for `BigDecimal ? float`
   > - `double`: `7n + 3`
   > 
   > So `float` wins once `2n > x - 3`, whatever finite `x` the table holds. 
For example, raising `BigDecimal ? float` from 5 to 10 fixes the calls in the 
issue, but `m(1, 2, 3, 4, d)` picks `float` again. `BigInteger` is already 14 
vs 12 in the table and still regresses at two `int` arguments.
   > 
   > To always lose, the value has to exceed anything the other arguments can 
add up to. At that point it isn't a ranking within the table any more but a 
separate penalty, so I kept it out of the table and named it.
   > 
   > **Why 2^19, i.e. a shift of 40?** You're right that `(dist << 21) + (1L << 
40)` is the same as adding 2^19 to the table value. The value only has to sit 
between two bounds:
   > 
   > - **Above** the largest total that the primitive and object distances of 
the other arguments can reach. Each primitive distance is at most 19 << 21 
(about 2^25.3), and object distances stay well below 2^34. So 2^40 can't be 
overtaken by any realistic number of arguments, and a lossy candidate can't tie 
with a non-lossy one again.
   > - **Below** `VARGS_SHIFT` (44), so the existing varargs ordering is kept. 
A lossy non-varargs method still beats a non-lossy varargs one, exactly as 
before. Bits 40-43 also leave room for up to 15 lossy arguments before the 
penalty spills into the varargs bits.
   > 
   > Bits 34-43 were already unused in practice, so I narrowed the documented 
object range to 23-39 and gave the penalty bits 40-43. Any value between about 
2^34 and 2^43 would work; 40 is just the most obviously safe choice.
   > 
   > If you'd prefer the penalty in the table, it could be a named constant 
(for example `LOSSY = 1 << 19`) added to the `BigDecimal`/`BigInteger` ? 
`float`/`Float` cells. The behaviour is identical, but those four cells would 
hold 524,000-odd among values of 0-19, so I thought a separate penalty was 
clearer.
   >
   > One point that's a real choice rather than an implementation detail: 
should a lossy non-varargs method beat a lossy-free varargs one? For example, 
with m(float) and m(double...), a BigDecimal argument currently picks m(float). 
The patch keeps that, which is the conservative option. Moving the penalty 
above VARGS_SHIFT would pick m(double...) instead. Jochen may have a view on 
that.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to