www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - ints.choice vs. chars.choice

reply mipri <mipri minimaltype.com> writes:
Howdy,

The following program fails to compile if the second line
is uncommented:

import std;

void main() {
     writeln([1, 2, 3].choice);
     //writeln(['a', 'b', 'c'].choice);
}

Error: template std.random.choice cannot deduce function from 
argument types !()(char[], MersenneTwisterEngine!(uint, 32LU, 
624LU, 397LU, 31LU, 2567483615u, 11LU, 4294967295u, 7LU, 
2636928640u, 15LU, 4022730752u, 18LU, 1812433253u)), candidates 
are:
/usr/include/dmd/phobos/std/random.d(2559):        
std.random.choice(Range, RandomGen = Random)(auto ref Range 
range, ref RandomGen urng) if (isRandomAccessRange!Range && 
hasLength!Range && isUniformRNG!RandomGen)
/usr/include/dmd/phobos/std/random.d(2569):        
std.random.choice(Range)(auto ref Range range)

What is going on here? I get it that choice() isn't simply an 
algorithm
over T[], that there are some additional constraints, but surely a
char[] is just as random acc...

...

Oh. It's because of emojicode.

This works:

import std;

void main() {
     writeln([1, 2, 3].choice);
     writeln(cast(char)(cast(uint8_t[])['a', 'b', 'c']).choice);
}

and this outputs false: writeln(isRandomAccessRange!(char[]));

I no longer have any questions but I wish the dlang.org docs were
much more generous with examples.
Nov 18 2019
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 11/18/19 12:32 PM, mipri wrote:
 Howdy,
 
 The following program fails to compile if the second line
 is uncommented:
 
 import std;
 
 void main() {
      writeln([1, 2, 3].choice);
      //writeln(['a', 'b', 'c'].choice);
 }
 
 Error: template std.random.choice cannot deduce function from argument 
 types !()(char[], MersenneTwisterEngine!(uint, 32LU, 624LU, 397LU, 31LU, 
 2567483615u, 11LU, 4294967295u, 7LU, 2636928640u, 15LU, 4022730752u, 
 18LU, 1812433253u)), candidates are:
 /usr/include/dmd/phobos/std/random.d(2559): std.random.choice(Range, 
 RandomGen = Random)(auto ref Range range, ref RandomGen urng) if 
 (isRandomAccessRange!Range && hasLength!Range && isUniformRNG!RandomGen)
 /usr/include/dmd/phobos/std/random.d(2569): 
 std.random.choice(Range)(auto ref Range range)
 
 What is going on here? I get it that choice() isn't simply an algorithm
 over T[], that there are some additional constraints, but surely a
 char[] is just as random acc...
Nope, phobos treats a narrow character array (such as char[] or wchar[]) as a bidirectional range of dchar. It's called autodecoding, and it's continually causing problems for about 10 years now.
 ....
 
 Oh. It's because of emojicode.
unicode. I hope that was a joke ;)
 This works:
 
 import std;
 
 void main() {
      writeln([1, 2, 3].choice);
      writeln(cast(char)(cast(uint8_t[])['a', 'b', 'c']).choice);
You could also use cast(dchar[]), and avoid the cast back to char. -Steve
Nov 18 2019
parent Daniel Kozak <kozzi11 gmail.com> writes:
On Mon, Nov 18, 2019 at 7:25 PM Steven Schveighoffer via
Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:
 You could also use cast(dchar[]), and avoid the cast back to char.

 -Steve
or use byCodeUnit writeln(['a', 'b', 'c'].byCodeUnit.choice);
Nov 18 2019