Expressions
The Random
class is one of many derived from the Expression class. Expression
objects implement lazy evaluation of mathematical expressions, as opposed to the eager evaluation that is the case otherwise. Many mathematical functions and operators are overloaded for Expression
objects; instead of evaluating immediately, they construct and return a further Expression
object.
Assume that we have variables $a$, $x$, and $c$, declared in code as:
a:Real <- 2.0;
x:Real <- 5.0;
c:Real <- -1.0;
Real
is a basic type. Mathematical operators and functions are overloaded for Real
to evaluate immediately. For example, in:
let y <- exp(a*x + c);
y
will have type Real
, and will contain the result of evaluation $\exp(ax + c) = \exp(2.0 \times 5.0 - 1.0) \approx 8103.08$.
On the other hand, if one or more of $a$, $x$, or $c$ has class type Expression<Real>
(including Random<Real>
, as it derives from Expression<Real>
):
a:Real <- 2.0;
x:Random<Real>;
c:Real <- -1.0;
Expression
object representing the expression itself, rather than its evaluation. If we repeat the previous statement:
let y <- exp(a*x + c);
y
will now have type Expression<Real>
. The expression can be evaluated later by calling y.value()
, although x
will need to be assigned a value first. There are two ways to do this. We could assign or simulate a value for x
:
x <- 5.0;
y.value()
. In this case the evaluated value is the same as for the example above. Alternatively, we could use the assume operator to associate a distribution with x
:
x ~ Gaussian(5.0, 4.0);
y.value()
is later called, a value will be simulated from that distribution and assigned to x
, in order to evaluate y
. The evaluated value will, of course, depend on that value.