June 14, 2016
On Tuesday, 14 June 2016 at 13:58:29 UTC, tsbockman wrote:
> Given the above, I believe we should move forward with `checkedint` as-is. Someone can add a `BoundInt` type to it later, if there is demand.

Ok. Thanks.
June 14, 2016
Thanks for doing this!

On 6/7/2016 1:50 AM, Robert burner Schadek wrote:
> == SmartInt ==
> SmartInt smartOp strive to actually give the mathematically correct answer
> whenever possible, rather than just signaling an error.
>
> == SafeInt ==
> SafeInt safeOp strive to match the behaviour of the basic integral types
> exactly, $(B except) that where the behaviour of the basic type is wrong, or
> very unintuitive, an error is signaled instead.


What the differences between these types are is unclear, for example, the former says "correct" and the latter says "not wrong". Also, "very unintuitive" has a pretty slippery meaning.

June 14, 2016
On 6/14/2016 4:25 PM, Walter Bright wrote:
> Thanks for doing this!
>
> On 6/7/2016 1:50 AM, Robert burner Schadek wrote:
>> == SmartInt ==
>> SmartInt smartOp strive to actually give the mathematically correct answer
>> whenever possible, rather than just signaling an error.
>>
>> == SafeInt ==
>> SafeInt safeOp strive to match the behaviour of the basic integral types
>> exactly, $(B except) that where the behaviour of the basic type is wrong, or
>> very unintuitive, an error is signaled instead.
>
>
> What the differences between these types are is unclear, for example, the former
> says "correct" and the latter says "not wrong". Also, "very unintuitive" has a
> pretty slippery meaning.
>

A better explanation:

http://dtest.thecybershadow.net/artifact/website-7cc6e938154f90aa49fa6451a85b13e35ab2de99-bc50ab8ca1b076e361ddc71d706010b7/web/phobos-prerelease/std_experimental_checkedint.html
June 14, 2016
Overall, I find the documentation to be unusually good. Nice work!

================================================

.noex

  The .noex member is oddly named, being a negative and no idea what 'ex' means. It sets a sticky flag on error, so perhaps .sticky?

---
N is a basic integral type, it needs a better name than 'N'. How about 'BaseType' or even 'BaseIntegralType'? A complete list of what types are acceptable for 'N' would be desirous, too.

---
'bscal' is a complete mystery without reading the documentation. Perhaps 'value' instead?

---
enum IntFlagPolicy policy;

  Should contain a link to the complete explanation.

---
Should have a "References:" section with link to core.checkedint

---
-O (DMD) should be a link to the -O flag instructions http://dlang.org/dmd-windows.html#switch-O

---
'--inline' is not a DMD switch

---
Remove all use of 'you' and 'your' from the documentation. For example:

"If you really need more speed, try switching to DebugInt for the hottest code in your program (like inner loops) before giving up on checkedint entirely."

becomes:

"For more speed, switch to DebugInt for the hottest code in the program (like inner loops)."

(The internal link to DebugInt is wrong.)

And:

"This way, you can use SafeInt!N to debug your integer logic in testing, but switch to basic N in release mode for maximum speed and the smallest binaries."

becomes:

"This way, use SafeInt!N to debug integer logic in testing, but switch to basic N in release mode for maximum speed and the smallest binaries."

Reference material should never contain "you" or "your".

---
"debuggin" => "debugging"

---
There's an overall lack of use of internal links to navigate within the page.

---
Functions are tagged @safe. Are there any unsafe functions?
June 15, 2016
On Wednesday, 15 June 2016 at 00:16:12 UTC, Walter Bright wrote:
> Overall, I find the documentation to be unusually good. Nice work!

Thanks. :-D

> ================================================
>
> .noex
>
>   The .noex member is oddly named, being a negative and no idea what 'ex' means. It sets a sticky flag on error, so perhaps .sticky?

Originally I wanted to have the policies just be `throws` and `nothrow` - but of course `nothrow` is a keyword, so I chose `noex` (short for "no exceptions") instead. I agree it looks kind of odd though, especially since I later added the `asserts` policy.

I'll consider renaming `noex`, or at least add an explanation of the mnemonic to the docs.

> ---
> N is a basic integral type, it needs a better name than 'N'. How about 'BaseType' or even 'BaseIntegralType'? A complete list of what types are acceptable for 'N' would be desirous, too.

`N` is not a public symbol, and it's used all over the place. Do I really need to give it some giant multi-word name?

Besides which, Phobos uses single-letter names for template parameter type names all over the place.

> ---
> 'bscal' is a complete mystery without reading the documentation. Perhaps 'value' instead?

`value` is a very popular name for function parameters and local variables. `bscal` needs a more obscure name to prevent the free function version (a shim to facilitate uniform treatment of basic integral types and checkedint types in generic code) from shadowing or being shadowed by local symbols.

(I originally called it `value`, but changed it once I realized how annoying it is not to be able to use that name for anything else in generic code that uses `checkedint`.)

Also, I prefer a more unfriendly name for `bscal` to remind people that accessing it entails giving up all of the safety benefits of `checkedint`. The fact that it's grep-able, too, could be helpful to linters and the like.

> ---
> enum IntFlagPolicy policy;
>
>   Should contain a link to the complete explanation.
>
> ---
> Should have a "References:" section with link to core.checkedint
>
> ---
> -O (DMD) should be a link to the -O flag instructions http://dlang.org/dmd-windows.html#switch-O
>
> ---
> '--inline' is not a DMD switch
>
> ---
> Remove all use of 'you' and 'your' from the documentation. For example:
>
> "If you really need more speed, try switching to DebugInt for the hottest code in your program (like inner loops) before giving up on checkedint entirely."
>
> becomes:
>
> "For more speed, switch to DebugInt for the hottest code in the program (like inner loops)."
>
> (The internal link to DebugInt is wrong.)
>
> And:
>
> "This way, you can use SafeInt!N to debug your integer logic in testing, but switch to basic N in release mode for maximum speed and the smallest binaries."
>
> becomes:
>
> "This way, use SafeInt!N to debug integer logic in testing, but switch to basic N in release mode for maximum speed and the smallest binaries."
>
> Reference material should never contain "you" or "your".
>
> ---
> "debuggin" => "debugging"
>
> ---
> There's an overall lack of use of internal links to navigate within the page.

I will work on the docs some more.

> ---
> Functions are tagged @safe. Are there any unsafe functions?

Sort of. There are a small number of template functions in `checkedint` that call some outside function whose @safety is unspecified, requiring the @safe-ty of the `checkedint` function to be inferred.

I believe the complete list currently is:

* SmartInt.toString(sink, fmt)
* SafeInt.toString(sink, fmt)
* checkedint.to()
* IntFlag.toString(sink, fmt)
* IntFlags.toString(sink, fmt)

(It would be great if we could fill in the gaps in D's attribute system - it's kind of ridiculous that for every attribute, there is at least one possible mode that cannot be indicated explicitly in any way.)
June 15, 2016
On Wednesday, 15 June 2016 at 00:16:12 UTC, Walter Bright wrote:
> A complete list of what types are acceptable for 'N' would be desirous, too.

This is specified fully in the template constraints:
    if (isIntegral!N && isUnqual!N)
    if ((isIntegral!N && !isUnqual!N) || isCheckedint!N)

The second overload simply forwards to the first, after applying BasicScalar!(Unqual!N).

However, I recall that new users tend to get confused/intimidated by template constraints, so I suppose I should add a prose explanation to the docs, as well.
June 14, 2016
On 6/14/2016 8:15 PM, tsbockman wrote:
>> N is a basic integral type, it needs a better name than 'N'. How about
>> 'BaseType' or even 'BaseIntegralType'? A complete list of what types are
>> acceptable for 'N' would be desirous, too.
>
> `N` is not a public symbol, and it's used all over the place.

It appears all over the public documentation.

> Do I really need to give it some giant multi-word name?

Something better than 'N'.

> Besides which, Phobos uses single-letter names for template parameter type names
> all over the place.

Generally 'T' is used for 'any type'. 'N' has no corresponding significance.

>> ---
>> 'bscal' is a complete mystery without reading the documentation. Perhaps
>> 'value' instead?
>
> `value` is a very popular name for function parameters and local variables.
> `bscal` needs a more obscure name to prevent the free function version (a shim
> to facilitate uniform treatment of basic integral types and checkedint types in
> generic code) from shadowing or being shadowed by local symbols.
>
> (I originally called it `value`, but changed it once I realized how annoying it
> is not to be able to use that name for anything else in generic code that uses
> `checkedint`.)
>
> Also, I prefer a more unfriendly name for `bscal` to remind people that
> accessing it entails giving up all of the safety benefits of `checkedint`. The
> fact that it's grep-able, too, could be helpful to linters and the like.

Greppability is inddeed a plus, but 'bscal' is needlessly uninformative. Note that publicly facing names should not be so.


> I will work on the docs some more.

Thank you.


> * SmartInt.toString(sink, fmt)
> * SafeInt.toString(sink, fmt)
> * checkedint.to()
> * IntFlag.toString(sink, fmt)
> * IntFlags.toString(sink, fmt)

I see no love for output ranges :-(

June 14, 2016
On 6/14/2016 8:23 PM, tsbockman wrote:
> On Wednesday, 15 June 2016 at 00:16:12 UTC, Walter Bright wrote:
>> A complete list of what types are acceptable for 'N' would be desirous, too.
>
> This is specified fully in the template constraints:
>     if (isIntegral!N && isUnqual!N)
>     if ((isIntegral!N && !isUnqual!N) || isCheckedint!N)
>
> The second overload simply forwards to the first, after applying
> BasicScalar!(Unqual!N).

Why would a checkedint be a base type for a checkedint?


> However, I recall that new users tend to get confused/intimidated by template
> constraints, so I suppose I should add a prose explanation to the docs, as well.

The fact that anyone has to write !isUnqual, i.e. a double negative, is crummy design. But that's not your fault :-)
June 15, 2016
On Wednesday, 15 June 2016 at 03:42:52 UTC, Walter Bright wrote:
> On 6/14/2016 8:15 PM, tsbockman wrote:
>> Do I really need to give it some giant multi-word name?
>
> Something better than 'N'.

`Int`? `Base`?

Whatever it is needs to be short; `BaseIntegralType` is *way* too long for this and would make many of the signatures painfully verbose.

>> Besides which, Phobos uses single-letter names for template parameter type names
>> all over the place.
>
> Generally 'T' is used for 'any type'. 'N' has no corresponding significance.

I have seen all of `S`, `F`, `G`, `X`, `R`, `C`, `A`, and `B` used as template parameter names in Phobos. Often there is no particular significance to the letter chosen, but the purpose of the parameter is obvious from the context, anyway.

Using short template parameter names helps keep D's already-very-long signatures from growing even longer than they already are.

> Greppability is inddeed a plus, but 'bscal' is needlessly uninformative. Note that publicly facing names should not be so.

`basic`? `base`?

Again, this needs to be short for readability and usability. Normally it's not needed at all, but when it is needed (like in the implementation of `SmartInt` and `SafeInt`), it tends to be needed *a lot*.

The obvious choices - `value`, `val`, or `raw` - are out because of the shadowing problem.

>> I will work on the docs some more.
>
> Thank you.
>
>
>> * SmartInt.toString(sink, fmt)
>> * SafeInt.toString(sink, fmt)
>> * checkedint.to()
>> * IntFlag.toString(sink, fmt)
>> * IntFlags.toString(sink, fmt)
>
> I see no love for output ranges :-(

I will add support. Someone should update this wiki page with whatever the current best practice is:
    http://wiki.dlang.org/Defining_custom_print_format_specifiers

June 15, 2016
On Wednesday, 15 June 2016 at 03:45:39 UTC, Walter Bright wrote:
> On 6/14/2016 8:23 PM, tsbockman wrote:
>> This is specified fully in the template constraints:
>>     if (isIntegral!N && isUnqual!N)
>>     if ((isIntegral!N && !isUnqual!N) || isCheckedint!N)
>>
>> The second overload simply forwards to the first, after applying
>> BasicScalar!(Unqual!N).
>
> Why would a checkedint be a base type for a checkedint?

Generic code (contrived, oversimplified example):

    import checkedint.throws, checkedint.traits;

    SmartInt!(typeof(A.init + B.init)) add(A, B)(const A a, const B b)
        if (isIntegral!A && isIntegral!B)
    {
        SmartInt!A ma = a;
        SmartInt!B mb = b;

        return ma + mb;
    }

Of course I could force the user to write `BasicScalar` everywhere - but why? The intent is just as clear this way, and it's less verbose.