-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
General floating point formatting in Debug with {:g?} #2729
Conversation
not clear what it was trying to show
Debug
with {:g?}
:
Note: If people were on board with the much simpler alternative of simply changing the output of (though one major question is how to deal with the precision flag, since changing it to count sig figs would change the meaning of every line of code that uses Debug with a precision; perhaps adding a precision always switches to fixed-point) |
Just braimstorming. As the format invocation and the format string parsing is generated by the compiler, what if instead of providing this single char (radix?) formating, let the user provide some generic trait impl for this functionality: To format numbers as hex. I don't know if it is possible to implement. It is just an idea that makes formting costomizable by users. |
Issue where the current behavior of |
This was attempted way back in rust-lang/rust#24612 but unfortunately this format change broke (and likely still breaks) real code, see rust-lang/rust#24612 (comment) |
Notice that the snippet in rust-lang/rust#24612 (comment) uses |
This is true but I don't think it's particularly relevant. The two snippets there are examples, not exhaustive: the specific library they're from has become largely irrelevant in the meantime, but the pattern (ensuring
I do not think it is useful to try to draw a distinction between "legitimate" and "illegitimate" here. |
Can't such code just switch from |
I was about to post on the internal threads, but I finally discovered this issue. Thanks for the detailed write-up @ExpHP! As someone working on numerical code every day, I am encountering this issue all the time. I consider the current Here's an example from my work today, using
I think it would be nice to get the proposed specifier, but can we no matter what please fix the I would also like to note that having a new format specifier also does not help me, because in many cases (such as the |
For completeness I'll also leave here parts of what I intended to post on the internals thread, before I discovered this RFC. I don't in any way intend any of this to supercede what @ExpHP presented - which is in any case much more thorough and well-researched, but just to serve as some (hopefully helpful) additional feedback.
|
Yes! This is precisely the kind of stuff that drives me to the solution of replacing
So, here, I'm actually going to play a bit of devil's advocate. Because of course, I agree with you; but as much as I like to argue that "people shouldn't be relying on Debug output," in retrospect it's not entirely fair to conclude from this that "therefore, there's no problem." I suppose at this point it is important for us to at least try and understand the reasons why people may be relying on it anyways; and who knows, perhaps discussing this could help us find a way to finally move forward? I can think of at least a couple of reasons somebody might depend on the output of
My gut feeling is that most breakage is probably unit test breakage like the second bullet, but I don't know for sure. It might also be worth looking back at the fallout of the change that added |
I completely agree - it's not a change that should be made lightly, and it's important to understand current use cases, but I'd also be wary of being overly cautious - in this case we might never see this change implemented, which is ultimately to the detriment of developers.
I can understand this sort of code for quick and dirty projects - I could see myself doing this for unimportant or very short-lived code. However, for any serious project, this is exactly the kind of "incorrect" use case I had in mind earlier - if you're actively going against the warnings of the documentation, then you'll have to be able to accept the consequences if the behavior changes in the future.
Yes, test code like this will break, that's true. I think, however, that must be considered acceptable breakage.
I hope so! Do you have an idea for an actionable plan for finding out about current use cases for the |
Hm. Well, while it only finds a relatively small portion of all code that will break, by far the most powerful tool at our disposal for discovering such possible problems is crater. In particular:
For the second bullet, from what I recall, it is not uncommon for experimental PRs to be filed against the Rust repo without the intent to merge, in order to have crater runs performed on them. I don't know if there's any more to the process than this. (Are eRFCs even still a thing? 🤷) In the meanwhile, I did a bit of looking into number 1 and here's what I found. Here's some notable links:
I would expect to find useful things in the linkbacks to these pages. The PR has very few linkbacks, but the crater issue has a couple, most notably some of the changes people made to fix the errors. These are all of the ones I noticed:
Unsurprisingly, all of these changes appear to simply be fixing failing tests, as evidenced by the fact that they all modify test code without modifying non-test code. However, I also notice something that I didn't consider before: I expected that these would all simply change the expected output string. In actuality, four out of five of these also changed the test, in order to make it produce the same output in both old and new versions of rust (e.g. using For the one crate that only changed expected outputs instead of tests (
...and I feel like this theme of "prevention" is similar to what I remarked above. |
Thanks for digging through this @ExpHP! That's some very useful insight. It strikes me that most people who rely on the current floating-point This is for example the case with the |
Hi @ExpHP, we discussed this RFC in today's libs team meeting and we agreed with the problem and solutions you've described. In particular we were most interested in the second alternative proposal you suggested in the RFC and in this comment:
We're much more apprehensive about adding a new formatting flags than we are about changing the As such we'd like to see an implementation of the proposed general float format as part of the default output of Also, our discussion did raise a few concerns that need to be resolved before we can merge the aforementioned PR:
Thanks again for the proposal and well written RFC! |
I will be referring to certain parts of this RFC from a rust-lang/rust PR (in particular the research on other languages) and wanted to make sure these details were present
I am now working on a PR to change Debug, but for the moment I'm going to post a bit about a consideration that is different for Choice of Thresholds for
|
Status: rust-lang/rust#86479 has made it through FCP. That PR makes automatic exponential the default output of Debug (suppressed when a precision is provided), which adequately addresses the motivations of this RFC. Thus, I'll be closing this for now as it seems obsolete. |
…, r=yaahc Automatic exponential formatting in Debug Context: See [this comment from the libs team](rust-lang/rfcs#2729 (comment)) --- Makes `"{:?}"` switch to exponential for floats based on magnitude. The libs team suggested exploring this idea in the discussion thread for RFC rust-lang/rfcs#2729. (**note:** this is **not** an implementation of the RFC; it is an implementation of one of the alternatives) Thresholds chosen were 1e-4 and 1e16. Justification described [here](rust-lang/rfcs#2729 (comment)). **This will require a crater run.** --- As mentioned in the commit message of 8731d4d, this behavior will not apply when a precision is supplied, because I wanted to preserve the following existing and useful behavior of `{:.PREC?}` (which recursively applies `{:.PREC}` to floats in a struct): ```rust assert_eq!( format!("{:.2?}", [100.0, 0.000004]), "[100.00, 0.00]", ) ``` I looked around and am not sure where there are any tests that actually use this in the test suite, though? All things considered, I'm surprised that this change did not seem to break even a single existing test in `x.py test --stage 2`. (even when I tried a smaller threshold of 1e6)
Rendered
Proposes extending
{:?}
with a general number floating point flagg
, similar to{:x?}
: