Lazy Parameter Evaluation in D Language

Written by on March 6, 2022 in D Language, Programming with 0 Comments

Languages such as C/C++ and Java follow an “eager” argument evaluation approach, where function arguments are evaluated before the function is entered. Of course, there are idioms and tricks that one can use to force “lazy” evaluation. The primary benefit of “lazy” parameter evaluation is that the parameter is evaluated only when it is used and this can improve efficiency. D language supports both “eager” and “lazy” parameter evaluations.

Here is a simple D program to show “eager” parameter evaluation:

Example Program

Example Program

 

If you study the function “fooBar”, it takes a boolean first parameter along with two integer params. Based on the value of the first param, it uses one of the other two params (not both) inside the body for computing its result.

Now look at the program output:

Eager Evaluation Result

Eager Evaluation Result

We see that both the functions are evaluated in each case. This is not surprising. Because by default, D language (like C, C++, Java) uses “eager evaluation“, when the “fooBar” function is called, both the second and third parameters are evaluated apriori, even though only one is actually used inside the function. One might argue that it is “wasteful” to call the other function that is not used in the result computation, especially if the calculation is “costly”.

The solution lies in “lazy” parameter evaluation. Here is the modified “fooBar” function:

Declaring Lazy Parameters

Declaring Lazy Parameters

I have added the extra qualifier “lazy” to the second and third parameters of “fooBar”. This forces the D compiler to evaluate the argument(s) only at the point of use, not apriori. This is confirmed by the output from the program.

Program Output

Program Output

Nice, isn’t it? There is a catch, though. While the positive aspect of declaring an argument as “lazy” is that the compiler evaluates it only when it is required, the negative side of it is that the compiler evaluates it “every” time it needs the parameter.

Let us modify our “fooBar” function slightly:

Multiple References to Lazy Param

Multiple References to Lazy Param

The change, as you would have noticed, is that I am using the lazy” parameters twice in each expression just to prove a point. When we run the program now, this is what we get:

Program Output

Program Output

Clearly, this is not what we want! Our decision to declare the parameters as “lazy” in the first place was to avoid unnecessary computation, but now the objective is lost!

So what is the way out? Simple really. We can evaluate the “lazy” parameter once and assign it to a different local variable and then use that local variable whenever we need the original parameter later in the function. This is shown below.

Caching the Parameter

Caching the Parameter

And here is the program output after the change:

Output After Caching

Output After Caching

That solves our problem! We now have the benefit of “lazy” parameter evaluation, at the same time avoiding multiple evaluations of that parameter. Ideally, the compiler should cache the result of the first evaluation and use it subsequently, but we can live with that limitation.

You can download the sample D program here.

Have a nice weekend!

Tags: ,

Subscribe

If you enjoyed this article, subscribe now to receive more just like it.

Subscribe via RSS Feed

Leave a Reply

Your email address will not be published.

Top