tvl-depot/tvix/eval/src/value
Florian Klink 1facd889bb feat(tvix/eval): use lexical-core to format float
Apparently our naive implementation of float formatting, which simply
used {:.5}, and trimmed trailing "0" strings not sufficient.

It wrongly trimmed numbers with zeroes but no decimal point, like
`10000` got trimmed to `1`.

Nix uses `std::to_string` on the double, which according to
https://en.cppreference.com/w/cpp/string/basic_string/to_string
is equivalent to `std::sprintf(buf, "%f", value)`.

https://en.cppreference.com/w/cpp/io/c/fprintf mentions this is treated
like this:

> Precision specifies the exact number of digits to appear after
> the decimal point character. The default precision is 6. In the
> alternative implementation decimal point character is written even if
> no digits follow it. For infinity and not-a-number conversion style
> see notes.

This doesn't seem to be the case though, and Nix uses scientific
notation in some cases.

There's a whole bunch of strategies to determine which is a more compact
notation, and which notation should be used for a given number.
https://github.com/rust-lang/rust/issues/24556 provides some pointers
into various rabbit holes for those interested.

This gist seems to be that currently a different formatting is not
exposed in rust directly, at least not for public consumption.

There is the
[lexical-core](https://github.com/Alexhuszagh/rust-lexical) crate
though, which provides a way to format floats with various strategies
and formats.

Change our implementation of `TotalDisplay` for the `Value::Float` case
to use that. We still need to do some post-processing, because Nix
always adds the sign in scientific notation (and there's no way to
configure lexical-core to do that), and lexical-core in some cases keeps
the trailing zeros.

Even with all that in place, there as a difference in `eval-okay-
fromjson.nix` (from tvix-tests), which I couldn't get to work. I updated
the fixture to a less problematic number.

With this, the testsuite passes again, and does for the upcoming CL
introducing builtins.fromTOML, and enabling the nix testsuite bits for
it, too.

Change-Id: Ie6fba5619e1d9fd7ce669a51594658b029057acc
Reviewed-on: https://cl.tvl.fyi/c/depot/+/7922
Tested-by: BuildkiteCI
Autosubmit: flokli <flokli@flokli.de>
Reviewed-by: tazjin <tazjin@tvl.su>
2023-01-25 07:49:44 +00:00
..
attrs refactor(tvix/eval): keep globals alive through VM struct 2023-01-20 22:48:13 +00:00
arbitrary.rs refactor(tvix/value): use proptest strategies from imbl crate 2023-01-17 10:20:38 +00:00
attrs.rs refactor(tvix/value): use proptest strategies from imbl crate 2023-01-17 10:20:38 +00:00
builtin.rs feat(tvix/eval): Add docstrings as documentation for builtins 2022-11-08 13:42:37 +00:00
function.rs fix(tvix/eval): fix current clippy warnings 2022-12-25 18:25:06 +00:00
list.rs refactor(tvix/value): use proptest strategies from imbl crate 2023-01-17 10:20:38 +00:00
mod.rs feat(tvix/eval): use lexical-core to format float 2023-01-25 07:49:44 +00:00
path.rs refactor(tvix/eval): factor out all calls to canon_path 2022-10-13 09:07:47 +00:00
string.rs feat(tvix/eval): implement builtins.toJSON 2023-01-12 10:42:44 +00:00
thunk.rs feat(tvix/eval): add error contexts to annotate error kinds 2023-01-20 15:39:51 +00:00