D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 18631 - std.random.choice does not work with const arrays
Summary: std.random.choice does not work with const arrays
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: phobos (show other issues)
Version: D2
Hardware: All All
: P1 normal
Assignee: No Owner
URL:
Keywords: pull
Depends on:
Blocks:
 
Reported: 2018-03-19 19:30 UTC by elpenguino+D
Modified: 2022-07-07 15:38 UTC (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description elpenguino+D 2018-03-19 19:30:39 UTC
```
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 github-bugzilla 2018-03-20 12:18:51 UTC
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 Jonathan M Davis 2018-03-23 19:03:48 UTC
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 Paul Backus 2022-02-23 21:11:18 UTC
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 Steven Schveighoffer 2022-07-04 20:58:00 UTC
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 Dlang Bot 2022-07-05 10:40:14 UTC
@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 Dlang Bot 2022-07-07 15:38:29 UTC
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