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]
