Thread overview
Improvement to std.numeric examples in documentation
Dec 28, 2019
BoraxMan
Dec 28, 2019
bachmeier
Dec 28, 2019
Paul Backus
Dec 28, 2019
BoraxMan
December 28, 2019
For the normalize function in std.numeric, I think an example of how to use bool normalize(R) where there is a sum value provided should be included.

The reason for this is that the examples given are as follows, and none show how the second sum parameter is given.

double[] a = [];
assert(!normalize(a));
a = [ 1.0, 3.0 ];
assert(normalize(a));
writeln(a); // [0.25, 0.75]
a = [ 0.0, 0.0 ];
assert(!normalize(a));
writeln(a); // [0.5, 0.5]

When one tries to do something like "normalize(a,10)", dmd reports this error.

> Error: template instance normalize!(no, 100) does not match template declaration normalize(R)(R range, ElementType!R sum = 1)

One must actually specify the template parameter, thus

> assert(normalise!(typeof(a)(a,100));

I guess for those more familiar with the language, this would be clear, but for those not as familiar just wanting to use a standard library function, they may be wondering why simply adding the second 'sum' parameter causes an error, or why IFTI isn't working.  I know I got a little stuck.




I also wonder why this second parameter means that DMD cannot deduce the type that (R) is.

December 28, 2019
On Saturday, 28 December 2019 at 03:28:33 UTC, BoraxMan wrote:
> For the normalize function in std.numeric, I think an example of how to use bool normalize(R) where there is a sum value provided should be included.
>
> The reason for this is that the examples given are as follows, and none show how the second sum parameter is given.
>
> double[] a = [];
> assert(!normalize(a));
> a = [ 1.0, 3.0 ];
> assert(normalize(a));
> writeln(a); // [0.25, 0.75]
> a = [ 0.0, 0.0 ];
> assert(!normalize(a));
> writeln(a); // [0.5, 0.5]
>
> When one tries to do something like "normalize(a,10)", dmd reports this error.
>
>> Error: template instance normalize!(no, 100) does not match template declaration normalize(R)(R range, ElementType!R sum = 1)
>
> One must actually specify the template parameter, thus
>
>> assert(normalise!(typeof(a)(a,100));
>
> I guess for those more familiar with the language, this would be clear, but for those not as familiar just wanting to use a standard library function, they may be wondering why simply adding the second 'sum' parameter causes an error, or why IFTI isn't working.  I know I got a little stuck.
>
>
>
>
> I also wonder why this second parameter means that DMD cannot deduce the type that (R) is.

Pull requests for documentation are usually handled quickly, and they're welcome if you've identified a hole in the existing documentation. Simply adding a new example can be handled by clicking "Improve This Page" in the upper right corner. I just did that recently and it took maybe an hour or two for my changes to be merged. If for some reason you don't want to do that, create a new issue.
December 28, 2019
On Saturday, 28 December 2019 at 03:28:33 UTC, BoraxMan wrote:
> When one tries to do something like "normalize(a,10)", dmd reports this error.
>
>> Error: template instance normalize!(no, 100) does not match template declaration normalize(R)(R range, ElementType!R sum = 1)
>
> One must actually specify the template parameter, thus
>
>> assert(normalise!(typeof(a)(a,100));

This looks like an instance of issue 1807 [1]. The fix is to move the alias template (in this case, ElementType) out of the argument list and into a template constraint:

bool normalize(R, S)(R range, S sum = 1)
    if (isForwardRange!R && is(S == ElementType!R))

You can work around this particular issue in your own code with the following wrapper function:

auto normalize(R, S)(R range, S sum)
    if (is(S == ElementType!R ))
{
    import std.numeric: normalize;
    return normalize!R(range, sum);
}

[1] https://issues.dlang.org/show_bug.cgi?id=1807
December 28, 2019
On Saturday, 28 December 2019 at 03:55:18 UTC, Paul Backus wrote:
> On Saturday, 28 December 2019 at 03:28:33 UTC, BoraxMan wrote:
>> When one tries to do something like "normalize(a,10)", dmd reports this error.
>>
>>> Error: template instance normalize!(no, 100) does not match template declaration normalize(R)(R range, ElementType!R sum = 1)
>>
>> One must actually specify the template parameter, thus
>>
>>> assert(normalise!(typeof(a)(a,100));
>
> This looks like an instance of issue 1807 [1]. The fix is to move the alias template (in this case, ElementType) out of the argument list and into a template constraint:
>
> bool normalize(R, S)(R range, S sum = 1)
>     if (isForwardRange!R && is(S == ElementType!R))
>
> You can work around this particular issue in your own code with the following wrapper function:
>
> auto normalize(R, S)(R range, S sum)
>     if (is(S == ElementType!R ))
> {
>     import std.numeric: normalize;
>     return normalize!R(range, sum);
> }
>
> [1] https://issues.dlang.org/show_bug.cgi?id=1807

Thanks for that.  I've created a pull request.  I ended up using my own version which was modified to correctly handle arrays of integers.  I think this function was specifically created only to work with floating points.  Either it should work with integers, or have a constraint where it won't accept integers.  Not sure what the original intent was.