Update overflow and trunctation docs post-Eigen - #721
Conversation
These needed to wait a bit more than the other docs, because the process of writing them uncovered the need for `SameRep` and `cast<T>`. Fixes #70.
| ```cpp | ||
| // Risky conversion caught when output rep specified: | ||
| Quantity<Inches, int8_t> length_in = length_ft.as<SameRep>(inches); | ||
| // Names the rep at the point of conversion ^^^^^^^^^ | ||
| ``` |
There was a problem hiding this comment.
So this is an interesting example. If I coding this, I'd naturally go for:
Quantity<Inches, int8_t> length_in = length_ft.as<int8_t>(inches);What I'm really concerned about is that my result fits in the destination type.
Actually, I'd likely use auto here, as I've already specified what I want on the right hand side, so what I'm getting on the left (in the auto) is pretty straight-forward to deduce:
auto length_in = length_ft.as<int8_t>(inches);All that to say, I'm not sure this is a great example of when SameRep would be used... I could maybe see it with:
auto length_in length_ft.as<SameRep>(inches);There was a problem hiding this comment.
Great callout. I really wrestled with what I was trying to say here.
I even realized there are actually three categories.
- Explicit rep
SameRep(as source)- Same rep as target
After reading your example, I had started working on an example where we assign to a field in a struct: it seemed better motivated and easier to understand than manually naming a type like Quantity<Inches, int8_t>. That was when I realized that neither explicit rep nor SameRep gives us what we want. The most ergonomic solution I could think of was something like:
convert_into(make_in_out(data.field), q, target_units);Obviously, make_in_out isn't something we could ship in Au; that uses Aurora-internal utilities. And I wouldn't want to just take a bare reference, because the callsite readability is poor! So actually adding a feature like this is not a clear slam dunk win. Moreover, it's very easy to write this utility in a client codebase without changing Au at all.
So Au natively supports the first two categories, and it's up to end users to support the third --- definitely today, possibly forever.
And I didn't want to muddle the docs with even more nuance.
So where does that leave us?
I ended up liking the auto in your final example the best. The auto actually pairs really nicely with the SameRep: it's a clear expression of author intent, "stay within the numeric type". I added a brief sentence after just saying that we dropped the explicit typename because it's now clearly determined by the RHS. As the above novel ^ indicates, yes, there is still a lot of subtlety lurking around these issues, but I'm hard pressed to improve this example any further at the moment.
|
|
||
| ### Compound types | ||
|
|
||
| Not every rep is a plain arithmetic type. Complex numbers, and Eigen vectors and matrices, are |
There was a problem hiding this comment.
| Not every rep is a plain arithmetic type. Complex numbers, and Eigen vectors and matrices, are | |
| Not every rep is a plain arithmetic type. Complex numbers and Eigen vectors and matrices, are |
I think the Eigen types are a single item in this list? With a third item, it would be:
Complex numbers, Eigen vectors and matrices, and Some Other Fun Library Type
are common examples ...
There was a problem hiding this comment.
I ended up doing "vectors/matrices", which avoids the confusion you pointed out here.
|
|
||
| Not every rep is a plain arithmetic type. Complex numbers, and Eigen vectors and matrices, are | ||
| common examples of _compound_ reps: types built up out of some underlying _scalar_. Au | ||
| characterizes each such rep by that scalar --- its |
There was a problem hiding this comment.
Yep --- I explicitly configured the site to replace --- with actual em-dashes in the rendered output. We were liberally using em-dashes long before the LLM era! 🤓
| a conservative approach. Any cast involving a rep with non-arithmetic scalar type, either as source | ||
| or destination, is considered to have truncation risk, and will not be allowed by default: users | ||
| must pass `ignore(TRUNCATION_RISK)` as a second argument to override this. We hope to have better | ||
| default behavior once we support non-arithmetic types more fully. |
There was a problem hiding this comment.
Do we want to reference #52 here as well?
| default behavior once we support non-arithmetic types more fully. | |
| default behavior once we support non-arithmetic types more fully ([#52]). |
There was a problem hiding this comment.
Done. In fact, I think it's better to reference it here only. The other one felt a little redundant, and the link makes more sense here.
These needed to wait a bit more than the other docs, because the process
of writing them uncovered the need for
SameRepandcast<T>.Fixes #70.