Boost logo

Boost :

From: Jens Maurer (Jens.Maurer_at_[hidden])
Date: 2003-04-15 17:07:42


Thorsten Ottosen wrote:
> To me the important thing here is that
> the modification of the internal state will not change the result of *any
> subsequent call* to any function on the object. The next call will
> always be the same random number. Yes, there is a state-change, but it
> cannot be observed.Only procedures can make such changes. Thus the function
> is logically const.

Please bear in mind that there are two different "kinds" of random
number engines: pseudo and non-deterministic ones. For the pseudo-random
number engines, a precise algorithm is given in the specification
which numbers are returned. The specification explicitly deals with
an internal state that is changed by each invocation of operator().
Some users of random numbers rely on that precise behavior. If
some other random number than the one specified would be returned,
this would be considered a bug. The reason is that a specific
pseudo-random number sequence has certain statistical properties
that can be examined. If an engine deviates from the sequence
specified, all theoretical reasoning about the statistical
properties breaks down.

Thus, I don't think such a function that, by specification, changes
the state in a defined way and makes subsequent function calls
return different (but well-defined) values, should be "const",
even by the broadest interpretation of "logically const".

For non-deterministic random numbers (such as those obtained
from an external hardware device), there's more of a point in
making operator() const. Since all pseudo-random number
generators' operator() are non-const, there's not enough
argument to convince me that this particular one should
stand out and be const.

> For the client a random number generator is just a black box that returns
> some numbers. The client doesn't care
> if there is an internal state change or if all the random sumbers are
> precalculated in some húge array (bad example :-), but then there wouldn't
> be any state change). The client just uses it to get some numbers.

People doing serious simulations certainly don't regard random numbers
as a black box. The need to know as much as possible about the
structure of the "black box". Please read the WG21 proposal at
http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1398.html
for some additional considerations.

> Now my question is what benefit does the client have of the random number
> generator to be non-const? After all, it will only
> mean he will often have to put mutable in front of his random number
> generater object.

This is certainly a valid option. Then, the user shows in his
class design that he indeed considers the detailed workings
of the random number generation an implementation detail in
his particular case.

> Also note the difference from std::rand()
> which can be called without problems from a function.

std::rand() uses a global variable in the C library to
store its state. The Boost.Random design makes the
storage of the state explicit by defining a class to
hold it. Thus, the analogy does not quite fit.

> Are we not making it harder for clients of the library? I think so.

I think it is bearable for any user of Boost.Random to be
aware of the basic functioning of a pseudo-random number
generator (changes local state when you call operator())
and take the appropriate action (add "mutable" to the random
number engine object) if he really wants to put it in a const
object.

Jens Maurer


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk