-
Notifications
You must be signed in to change notification settings - Fork 69
Add support for floats #34
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code looks really good! Thanks so much for taking the time. A few minor minor comments, and then I'll start the merge. So you are aware, the merge process requires someone else at Facebook to look at this diff with our internal tooling and CI, and if they have any comments that are minor I'll make the small tweaks, but if they have larger comments I'll come back to you. I don't foresee any issues though, since I've reviewed it thoroughly, and it really is excellent.
starlark/src/stdlib/funcs.rs
Outdated
Ok(if b { 1.0 } else { 0.0 }) | ||
} else { | ||
Err(anyhow!( | ||
"float() argument must be a string or a number, not '{}'", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We tend to use backticks around fragments of stuff in an error message.
"int() cannot convert non-string with explicit base '{}'", | ||
base.to_repr() | ||
)) | ||
} else if let Some(Num::Float(f)) = a.unpack_num() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we add some more test cases above for int on float
starlark/src/values/num.rs
Outdated
|
||
//! Helpers for numerical values. | ||
|
||
use super::Value; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We tend to avoid use super
use super::Value; | ||
|
||
#[derive(Clone, Copy, Debug)] | ||
pub enum Num { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we have some comments as to the purpose of this type, since it is both subtle and fundamental to this patch. My understanding is that we introduce Num
so that things that operate on any numeric types (e.g. add) can easily be written in a way that deals with both. I imagine one day we'll have a BigInt type which also lives in this region. Is that accurate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's exactly the idea. I was even thinking if I should move the arithmetic operations from int
and float
to Num
. It could be done in this PR or with some future work on BigInt.
@ndmitchell has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator. |
//! The floating point number type (3.14, 4e2). | ||
|
||
use std::cmp::Ordering; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
delete the blank line
"NaN".to_string() | ||
} else if self.is_infinite() { | ||
if self.is_sign_positive() { | ||
"Infinity" | ||
} else { | ||
"-Infinity" | ||
} | ||
.to_string() | ||
} else { | ||
self.to_string() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
every branch as a to_string
, you can pull that out and do if ... else { ... }.to_string()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The to_string
in the final branch is a different to_string, since it is going from f64, not a &str
. As it happens, I changed these to to_owned
in the mirror I put up, since one of our linters requests that - but left the positioning the same.
// This shouldn't happen as we handle potential NaNs above | ||
ValueError::unsupported_with(self, "==", other) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is unreachable
more appropriate here, since logically, we should never hit the case where f64's partial_cmp
returns Non
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't trust floating point values enough. There are so many weird special cases, i think having a default be an anyhow error rather than an unreachable is safer.
assert.eq(float(p53+1), p53+0) # | ||
assert.eq(float(p53+2), p53+2) | ||
assert.eq(float(p53+3), p53+4) # | ||
assert.eq(float(p53+4), p53+4) | ||
assert.eq(float(p53+5), p53+4) # | ||
assert.eq(float(p53+6), p53+6) | ||
assert.eq(float(p53+7), p53+8) # |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do these lines end with a trailing #
, did you intend on adding some comments?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those come directly from https://github.com/google/starlark-go/blob/87f333178d5942de51b193111d6f636c79833ea5/starlark/testdata/float.star#L49 I think the original author wanted to point out the cases where float loses precision.
I did only some formatting changes to that file to allow for easier discarding of nonconformant lines:
0a1,3
> # @generated
> # Copied from https://github.com/google/starlark-go/blob/87f333178d5942de51b193111d6f636c79833ea5/starlark/testdata/
>
237,239c240
< assert.eq(
< str(sorted([inf, neginf, nan, 1e300, -1e300, 1.0, -1.0, 1, -1, 1e-300, -1e-300, 0, 0.0, negzero, 1e-300, -1e-300])),
< "[-inf, -1e+300, -1.0, -1, -1e-300, -1e-300, 0, 0.0, -0.0, 1e-300, 1e-300, 1.0, 1, 1e+300, +inf, nan]")
---
> assert.eq(str(sorted([inf, neginf, nan, 1e300, -1e300, 1.0, -1.0, 1, -1, 1e-300, -1e-300, 0, 0.0, negzero, 1e-300, -1e-300])), "[-inf, -1e+300, -1.0, -1, -1e-300, -1e-300, 0, 0.0, -0.0, 1e-300, 1e-300, 1.0, 1, 1e+300, +inf, nan]")
384,385c385,390
< for a in [1.23e100, 1.23e10, 1.23e1, 1.23,
< 1, 4294967295, 8589934591, 9223372036854775807]:
---
> for a in [
> 1.23e100, # int overflow in starlark-rust
> 1.23e10, # int overflow in starlark-rust
> 1.23e1, 1.23, 1,
> 4294967295, 8589934591, 9223372036854775807, # int overflow in starlark-rust
> ]:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file is from Bazel, so nothing to do with us :)
@pierd - leave those changes from @bobyangyf with me - I'll make them on the internal copy I mirrored, as I had to make a few small formatting fixes in the import. |
To keep you updated, it was in the process of being merged when the current Facebook outage happened, which has delayed the merge. I made a few formatting and whitespace tweaks, fixed some error messages, but very little. Hopefully this will land tomorrow. |
No worries, thanks for the update. |
All merged! There was one last remark about -0.0 and 0.0 need to hash to the same thing which I tweaked, but otherwise it's the same. After that, as part of the move to have Thanks very much for your contribution 🥇 |
Addresses: #3
Spec: https://github.com/bazelbuild/starlark/blob/689f54426951638ef5b7c41a14d8fc48e65c5f77/spec.md#floating-point-numbers
Changes:
/
and/=
operators for divisionfloat
functionSimpleValue
for float (backed byf64
)assert_lt
implementation (required for some conformance tests)float.star
from starlark-go (with some formatting for easier nonconformant line removal)Known issues:
str
for floats doesn't conform to the spec