Bug 18631 – std.random.choice does not work with const arrays

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2018-03-19T19:30:39Z
Last change time
2022-07-07T15:38:29Z
Keywords
pull
Assigned to
No Owner
Creator
elpenguino+D

Comments

Comment #0 by elpenguino+D — 2018-03-19T19:30:39Z
``` const x = [1,2]; auto y = choice(x); ``` results in ``` /dlang/dmd/linux/bin64/../../src/phobos/std/random.d(2033): Error: template std.random.choice cannot deduce function from argument types !()(const(int[]), MersenneTwisterEngine!(uint, 32LU, 624LU, 397LU, 31LU, 2567483615u, 11LU, 4294967295u, 7LU, 2636928640u, 15LU, 4022730752u, 18LU, 1812433253u)), candidates are: /dlang/dmd/linux/bin64/../../src/phobos/std/random.d(2020): std.random.choice(Range, RandomGen = Random)(auto ref Range range, ref RandomGen urng) if (isRandomAccessRange!Range && hasLength!Range && isUniformRNG!RandomGen) /dlang/dmd/linux/bin64/../../src/phobos/std/random.d(2031): std.random.choice(Range)(auto ref Range range) onlineapp.d(5): Error: template instance `std.random.choice!(const(int[]))` error instantiating ``` It appears that the only thing keeping this from working is x not being a range, but the body of the function does not seem to actually require that be true.
Comment #1 by github-bugzilla — 2018-03-20T12:18:51Z
Commits pushed to master at https://github.com/dlang/phobos https://github.com/dlang/phobos/commit/403141166b624c47cafcb5904724b62271f63785 fix issue 18631 - Allow choice to work with const arrays https://github.com/dlang/phobos/commit/b99915397b376cde180f6ef3cc187e0046a97422 Merge pull request #6302 from BBasile/choice-const-rndrange fix issue 18631 - Allow choice to work with const arrays
Comment #2 by issues.dlang — 2018-03-23T19:03:48Z
The fix that was merged broke code and has been reverted: https://github.com/dlang/phobos/pull/6331 A different solution is required.
Comment #3 by snarwin+bugzilla — 2022-02-23T21:11:18Z
This is a special case of a general problem with ranges and const. A const object cannot implement popFront (which mutates its receiver), and therefore cannot be a range. In this case, the problem can be worked around by using the [] operator to obtain a mutable slice over the const array: --- const x = [1, 2]; auto y = choice(x[]); --- *** This issue has been marked as a duplicate of issue 17771 ***
Comment #4 by schveiguy — 2022-07-04T20:58:00Z
This is not a duplicate of the general foreach problem. It's specific to choice. Other range-accepting functions work with const arrays just fine. This is a problem with choice. The fix is to remove the `auto ref` modifier on the range, which is nonsensical, since it doesn't actually modify the range at all. It probably was a premature optimization (verified it has been there from the start).
Comment #5 by dlang-bot — 2022-07-05T10:40:14Z
@GrimMaple created dlang/phobos pull request #8495 "Fix Issue 18631 - std.random.choice does not work with const arrays" fixing this issue: - Fix Issue 18631 - std.random.choice does not work with const arrays `auto ref` is not needed on `Range` param https://github.com/dlang/phobos/pull/8495
Comment #6 by dlang-bot — 2022-07-07T15:38:29Z
dlang/phobos pull request #8495 "Fix Issue 18631 - std.random.choice does not work with const arrays" was merged into master: - ee474f0cfc543e844bcbcf96a0da17fc3bf8c8f4 by Grim Maple: Fix Issue 18631 - std.random.choice does not work with const arrays `auto ref` is not needed on `Range` param https://github.com/dlang/phobos/pull/8495