Too complicated code for generating a random string?
monarch_dodra
monarchdodra at gmail.com
Sat Feb 23 08:41:36 PST 2013
On Saturday, 23 February 2013 at 16:25:45 UTC, Andrei
Alexandrescu wrote:
> On 2/23/13 4:25 PM, Jens Mueller wrote:
>> auto randomLetter = () => letters[uniform (0,
>> letters.length)];
>> auto randomString = iota(10).map!(_ =>
>> randomLetter()).array();
>
> auto randomString = iota(10).map!(_ => letters[uniform(0,
> $)]).array;
>
> Bearophile has long asked for a one-parameter uniform(n) that
> does what uniform(0, n) does. Perhaps this provides a good
> supporting argument. With that enhancement:
>
> auto randomString = iota(10).map!(_ =>
> letters[uniform($)]).array;
>
> I expect this to be fast and only allocate once.
>
>
> Andrei
I'm still not a fan of the iota+map combo.
I wrote this (Fast)Generator template. The generic "generator"
bookkeeps the calls to front and popFront.
The "fast" variant assumes that you'll basically just call
front+popFront+front+popFront, or that you don't about bookeeping.
This can be interesting, as often, iota+map is straight up
linearly consumed.
//----
import std.stdio, std.range, std.conv, std.random;
template zeroaryFun(alias fun)
{
static if (is(typeof(fun) : string))
{
auto zeroaryFun()
{
mixin("return (" ~ fun ~ ");");
}
}
else
{
alias fun zeroaryFun;
}
}
struct FastGenerator(alias F)
{
private alias fun = zeroaryFun!F;
private alias T = typeof(fun());
enum empty = false;
@property auto front() {return fun();}
void popFront() {}
}
struct Generator(alias F)
{
private alias fun = zeroaryFun!F;
private alias T = typeof(fun());
private T cache;
private bool called = false;
enum empty = false;
@property
auto front()
{
if (!called)
{
cache = fun();
called = true;
}
return cache;
}
void popFront()
{
if (!called)
fun();
called = false;
}
}
void main()
{
dstring letters = "abcd";
int i = 0;
writeln(FastGenerator!(() => (i++))().take(9)); //Who needs
iota?
writeln(FastGenerator!"'s'"().take(5)); //Who needs repeat?
writeln(FastGenerator!(() => letters[uniform(0,
$)])().take(9)); //Simple,clear,concise.
}
//----
In these cases, Generator is something that is both convenient
and fast.
I realize it's not an incredibly higher order function or
anything, but I wouldn't mind having something like this in
Phobos. It would just make every day coding that much more
convenient and simple.
More information about the Digitalmars-d
mailing list