Andrei Alexandrescu wrote:
bearophile wrote:
Andrei Alexandrescu:
3. How should the global rng be initialized?
Automatically seeded with the time at the beginning of the program. Of
course the seed can be set again in any moment.
4. While we're at it, should uniform(a, b) generate by default
something in [a, b] or [a, b)? Someone once explained to me that
generating [a, b] for floating point numbers is the source of all
evils and that Hitler, Stalin and Kim Il Sung (should he still be
alive) must be using that kind of generator. Conversely, generating
[a, b) is guaranteed to bring in the long term everlasting peace to
Earth. My problem however is that in the integer realm I always want
to generate [a, b]. Furthermore, I wouldn't be happy if the shape of
the interval was different for integers and floating point numbers.
How to break this conundrum? Don't forget that we're only worrying
about defaults, explicit generation is always possible with
self-explanatory code:
auto rng = Random(unpredictableSeed);
auto a = 0.0, b = 1.0;
auto x1 = uniform!("[]")(rng, a, b);
auto x2 = uniform!("[)")(rng, a, b);
auto x3 = uniform!("(]")(rng, a, b);
auto x4 = uniform!("()")(rng, a, b);
That's awful and ugly. My suggestions are simple (copied from my dlibs
and the random std lib of Python):
random() => floating point [0, 1)
randInt(a=0, b) => integral [a, b]
randRange(a=0, b) => integral [a, b)
uniform(a, b) => floating point [a, b)
normal(a, b) => good quality normally-distributed number with given
std dev and avg.
Leaving normal() aside (does your implementation implement the ziggurat
algorithm? If so, would you agree to contribute it to phobos?), I don't
see how having to memorize four names instead of one is necessarily
awesome and beautiful. Besides uniform() renders "random" redundant.
Hardly a pinnacle of good API design, see realloc() which essentially
makes malloc() and free() redundant.
Andrei
your example counters your claim.
The same reason we prefer to use D with so many concepts and keywords
over something like brainf**k that is turing-complete with just 8 or so
commands can be apllied here.
sure, the *implementation* of realloc() makes the *implementations* of
free() and malloc() redundunt but it's easier to remember to use free()
when you actually want to free something. if free() wasn't available,
the first thing I'd do was to use a macro to define it.