Values are functions! Examples:
val(3) val("Hello, World")
The first evaluates to a nullary function (a function taking no arguments)
that returns an int
, 3
. The second evaluates to a nullary function
that returns a char const(&)[13]
, "Hello,
World"
.
Confused? val(3)
is a unary
function, you say? Yes it is. However, read carefully: "evaluates
to a nullary function". val(3)
evaluates to (returns) a nullary function. Aha! val(3)
returns a function! So, since val(3)
returns a function, you can invoke it. Example:
std::cout << val(3)() << std::endl;
(See values.cpp)
The second function call (the one with no arguments) calls the nullary
function which then returns 3
.
The need for a second function call is the reason why the function is said
to be Lazily Evaluated.
The first call doesn't do anything. You need a second call to finally evaluate
the thing. The first call lazily evaluates the function; i.e. doesn't do
anything and defers the evaluation for later.
It may not be immediately apparent how lazy evaluation can be useful by
just looking at the example above. Putting the first and second function
call in a single line is really not very useful. However, thinking of
val(3)
as a callback
function (and in most cases they are actually used that way), will make
it clear. Example:
template <typename F> void print(F f) { cout << f() << endl; } int main() { print(val(3)); print(val("Hello World")); return 0; }
(See callback.cpp)