Boost logo

Boost :

Subject: Re: [boost] a safe integer library
From: Robert Ramey (ramey_at_[hidden])
Date: 2016-01-13 12:07:42


On 1/13/16 6:58 AM, Brook Milligan wrote:
>
>> On Jan 12, 2016, at 10:36 PM, Robert Ramey <ramey_at_[hidden]> wrote:
>>
>> Within the design intention of the library of the library one would simply
>>
>>
>> safe_... x;
>> int y
>>
>> try{
>> y = x; // or x = y;
>> }
>> catch(cont std::exception e &){
>> // cast failed
>> …
>> }

> Is there some reason that this use case--inquiring about the potential safety
  of a value—should not be an inherent element of the design?
Is it not a valid use case to have a value in a wide type for
which one needs to know whether it can be converted to a particular safe
type?
Is this not required for some aspects of interoperability with
“non-safe” types?

As you've noticed, the functionality you're referring to has to be part
of such a library implementation. In the course of making the library,
I decided that this functionality was interesting in it's own right and
important for future evolution of the library (safe_money anyone?). So
I documented these implementation features - checked_result, checked and
interval. And each of these "sub-libraries" has it's own set of tests
and documentation pages. Maybe they should be three separate libraries.

But this opens up a huge amount of new territory. I have to limit the
scope in order to actually deliver something. So it's safe integer.

So to me, your question would be - why aren't these "libraries" exposed
to the end user. The short answer is: it's a lot of work to make a
library useful to an end user. One needs:

a) correctly factored code
b) correctly documented code
c) tutorial examples and use cases. - which requires going back to a)

Which doesn't sound all that bad. But the problem is that by the time
you get c) done, you can't help but discover that a) and b) need to be
updated - which turns out to be a lot more time consuming than first
meets the eye.

If I were to continue on this, I'd make the example/use case for
extending the library beyond integers to user-defined integer like types
such as "money". But that would feed back to ... - I'm not sure. But
surely this would be a lot more work. And I've worked on this waaaaay
past my original intention. Then there is the question of demand for
such a thing. The demand and interest for such a library such as safe
integer is much, much much less than I anticipated. So I'm not very
excited on spending more time on it.

As an aside there has been work on similar to parts of the library

a) Interval library.

1) Boost Interval Library. Speaking from memory, this has more emphasis
on floating point issues such as rounding and such. I don't remember if
it placed so much emphasis on operator overloading to make it easily
plug in compatible. I don't think it specifically addressed integer
problems such as converting between integer types, overflows and the
like. Didn't work at compile time.

2) Bruno Laland (?) had a compile time interval library. It was
undocumented and didn't handle the corner cases of overflow etc.

So this argued for making Interval as a library.

b) checked operations. This is sort of no brainer. It almost has to be
way it is. There are lots of libraries like this. But I couldn't find
one which which was factored right, supported constexpr and had compile
time handling to avoid unnecessary operations. For wider use, this
would have to be modified to define the template types for other than
integers. This could turn out to be stickier than meets the eye.

c) checked_result. This seems obvious in retrospect - but it wasn't
until I spend significant time iterating the loop above. This is
basically boost optional with more than one failure condition. In my
recollection there was a huge discussion about such a component as part
of the review for AFIO. I never understood what the big deal was. But
whenever the term "monad" gets injected into the discussion, things tend
to start circling the drain. It was certainly tricky. I wanted to use
Boost variant (or some other variant) but these are not literal types so
can't be used with constexpr. And there is the problem of implicit
conversions which I had a lot of difficulty getting correct - assuming
they are even now.

So there you have it. Three libraries which are mostly implemented and
documented - missing examples and use cases. If you want to make a name
for yourself, you could split out any of these and propose it as boost
library - or just use it as is, or make the extra documentation and
tests and I'll consider adding it to the safe integer library.

> I am left wondering why something as basic as this is so controversial, especially given that
there seem to be no runtime costs in exactly the same set of cases for
which the above code has
no runtime costs. Why sacrifice code clarity by not supporting this?

I don't think I'm sacrificing code clarity. I hope the above gives some
insight.

Robert Ramey


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk