## digitalmars.D - repost: semantics of the keyword lazy

• Karen Lanrap (37/37) Oct 11 2006 I have posted the following in the learn-group without any answers:
• Derek Parnell (23/59) Oct 11 2006 I have not read that way at all. To me this is not a circular definition...
• Hasan Aljudy (3/3) Oct 11 2006 I was wondering what would happen if you call the lazy "delegate"
• Derek Parnell (8/11) Oct 12 2006 It is called each time and the values are not cached.
• Karen Lanrap (27/28) Oct 12 2006 Hopefully the programmer has full control over what the called
• Ivan Senji (16/28) Oct 12 2006 This is not a circular definition.
• Karen Lanrap (10/12) Oct 13 2006 If it is not circular, then without using a self reference one should
Karen Lanrap <karen digitaldaemon.com> writes:
```I have posted the following in the learn-group without any answers:

From the documentation:

Lazy arguments are evaluated not when the function is called, but
when the parameter is evaluated within the function.

First to note, that this is a circular definition without any fixed
point to start from:
a lazy argument is evaluated, when it is evaluated :-(

Maybe Walter meant something like this:
With the exception of lazy parameters all actual parameters are
passed evaluated to the function they belong to.

But this does not help for lazy parameters: when the hell are they
evaluated?

"Within the function" Walters says. But what does this mean if the
calling function is recursive or combined with parameters that are
not lazy evaluated? Example:

int ack( lazy bool b, int x, lazy int y){
if( x == 0 )
if( b) return y+1;
else
if( y == 0)
return ack( b, x-1, 1);
else
return ack( b, x-1, ack( b, x, y-1));
}

If Walter wanted to express, that lazy parameters must be evaluated
in the calling function, then I understand, but I doubt, that this
concept is that useful.

If on the other hand lazy parameters can be passed down through
function hierarchies one should be able to protect them from
accidental evaluation until they reach the target point of their
evaluation, i.e. something like

if( unlazy b) return y+1;

should be possible and

ack( x, b, y-1)

should show up as an error because the target is not notified as

ack( x, unlazy b, y-1)
```
Oct 11 2006
Derek Parnell <derek nomail.afraid.org> writes:
```On Thu, 12 Oct 2006 03:08:07 +0000 (UTC), Karen Lanrap wrote:

I have posted the following in the learn-group without any answers:

From the documentation:

Lazy arguments are evaluated not when the function is called, but
when the parameter is evaluated within the function.

First to note, that this is a circular definition without any fixed
point to start from:
a lazy argument is evaluated, when it is evaluated :-(

I have not read that way at all. To me this is not a circular definition.

Non-lazy arguments are evaluated by the code that initiates the call to the
function. Lazy ones are evaluated by code that lies inside the function;
that is they are evaluated after the function is called, by your code in
the function.

Maybe Walter meant something like this:
With the exception of lazy parameters all actual parameters are
passed evaluated to the function they belong to.

That is exactly what he meant and said.

But this does not help for lazy parameters: when the hell are they
evaluated?

Whenever the called function decides to do it, if at all. To evaluate a
lazy argument, the function must explicitly call the delegate (which the
lazy argument represents).

"Within the function" Walters says. But what does this mean if the
calling function is recursive or combined with parameters that are
not lazy evaluated? Example:

int ack( lazy bool b, int x, lazy int y){
if( x == 0 )
if( b) return y+1;
else
if( y == 0)
return ack( b, x-1, 1);
else
return ack( b, x-1, ack( b, x, y-1));
}

If Walter wanted to express, that lazy parameters must be evaluated
in the calling function, then I understand, but I doubt, that this
concept is that useful.

But that is exactly what they are. It just means that the function
evaluates them by treating them as delegates and calling them, using the
result as the evaluated value.

If on the other hand lazy parameters can be passed down through
function hierarchies one should be able to protect them from
accidental evaluation until they reach the target point of their
evaluation

'accidental'? They are passed down as delegates and only evaluated if
explicitly called. No accident.

--
Derek
(skype: derek.j.parnell)
Melbourne, Australia
"Down with mediocrity!"
12/10/2006 1:49:14 PM
```
Oct 11 2006
Hasan Aljudy <hasan.aljudy gmail.com> writes:
```I was wondering what would happen if you call the lazy "delegate"
multiple times. will the result be cached or will the delegate/function
be called multiple times?
```
Oct 11 2006
Derek Parnell <derek nomail.afraid.org> writes:
```On Wed, 11 Oct 2006 22:56:59 -0600, Hasan Aljudy wrote:

I was wondering what would happen if you call the lazy "delegate"
multiple times. will the result be cached or will the delegate/function
be called multiple times?

It is called each time and the values are not cached.

--
Derek
(skype: derek.j.parnell)
Melbourne, Australia
"Down with mediocrity!"
12/10/2006 5:05:00 PM
```
Oct 12 2006
Karen Lanrap <karen digitaldaemon.com> writes:
```Derek Parnell wrote:

Whenever the called function decides to do it, if at all.

Hopefully the programmer has full control over what the called
function decides :-(

Another try:

The evaluation of actual parameters can be delayed to any level in
the call hierarchy.

If the evaluation of an actual parameter has to be delayed by at
least one level, then the type of the formal parameter has to be
prefixed by the keyword 'lazy'.

If in a called function 'foo' a formal lazy parameter is passed to
another called function 'bar' as a reference, i.e. without appended
parentheses, on a position where a lazy parameter is expected, then
the actual parameter is not evaluated in 'foo'. In all other cases
of
reached usage the actual parameter is evaluated.

Example:
int ack( lazy int x, lazy int y){
// ...
return ack( x-1, ack( x, y-1));
// this actual parameter  ^
// is not evaluated, but passed down only

// wheras
return ack( x-1, ack( x(), y-1));
// this actual parameter    ^
// _is_ evaluated and then passed down
}

Did I get that correctly?
```
Oct 12 2006
Ivan Senji <ivan.senji_REMOVE_ _THIS__gmail.com> writes:
```Karen Lanrap wrote:
I have posted the following in the learn-group without any answers:

From the documentation:

Lazy arguments are evaluated not when the function is called, but
when the parameter is evaluated within the function.

First to note, that this is a circular definition without any fixed
point to start from:
a lazy argument is evaluated, when it is evaluated :-(

This is not a circular definition.
import std.stdio;

void func(lazy int x) // x is a parameter
{
writefln(x()); //parameter evaluated here
writefln(x()); //and once again here
}

void main()
{
int x;
func({return x++;}());

//{return x++;}() is and argument and it is not called here
}

The thing is: argument and parameter are not one and the same and that
makes the definition not circular.
```
Oct 12 2006
Karen Lanrap <karen digitaldaemon.com> writes:
```Ivan Senji wrote:

The thing is: argument and parameter are not one and the same
and that makes the definition not circular.

If it is not circular, then without using a self reference one should
be able to explain where the point of evaluation is. But i do not see
such an explanation.

If you are right, that arguemnt and parameter are always not the
same, then this would mean, that the compiler has to construct a
delegate even then, when the argument is a delegate already. But then
a lazy evaluation of the ackermann-function for example would mean,
that the compiler has to construct a delegate---which's length is
approximately the length of the number to be output.
```
Oct 13 2006