But... I don't want my delegates to be lazy - breeding advice

BCS BCS at pathlink.com
Thu Aug 24 09:00:37 PDT 2006


Andy Knowles wrote:
> Walter Bright wrote:
> 
>> Ok, I've thought about it a bit:
>>
>>     void foo(int x);    // same as before 0.165
>>     void foo(int delegate() x)    // same as before 0.165
>>
>> and now:
>>
>>     void foo(lazy int x);
>>
>> In other words, 'lazy' is now a parameter storage class. This means that:
>>
>>     void foo(int x);
>>     void foo(lazy int x);
>>
>> cannot be distinguished based on overloading, but:
>>
>>     void foo(lazy int x);
>>     void foo(int delegate() x);
>>
>> can be. The implicit conversion of a value to a delegate returning 
>> that value would be removed. The conversion happens always (not 
>> implicitly) if the parameter storage class is 'lazy'.
> 
> 

I like that a lot better.

> I think that is definitely a step in the right direction, and I think it 
> will make people a lot more comfortable.

(I'm one of the above mentioned people)

> 
> Some questions:
> 
> 1) While in void foo(lazy int x) will x be evaluated using x() or just 
> x?  Either one could lead to confusion.
> 

I'd go for "x()", because

1> it more closely reflects what is actually happening.

2> it allows x to be used to refer to the delegate

3> it is semantically different than a value parameter. This will force 
you to look at each use while converting a function to lazy use. This is 
coming from the "when its easy, broken code shouldn't compile" school of 
thought.

OTOH

pros for the "x" version

1> the compiler could handle the code to detect the first usage and 
evaluate it once and use the evaluated version thereafter.

This would automate the generation and optimization of a lot of "hard to 
follow code". However that would be to much to trust the compiler in if 
you ask me. But it would make for some neat code.


void foo(Person[] people, lazy char[] here)
{
	foreach(man;people)
		if(man.IsHere)
			writef(man.name ~" is at "~here~\n);
}


becomes

void foo(Person[] people, lazy char[] here)
{
	int __j;
	foreach(__i, man;people)
		if(man.IsHere)
		{
			__j = __i;
			goto __eval;
		}

	return;

	__eval:
	char[] __here = EVAL(here);	// sudo code
			writef(people[__j].name ~" is at "~__here~\n);

	foreach(man;people[__j+1..$)
		if(man.IsHere)
			writef(man.name ~" is at "~__here~\n);
	
}

Vary tight code. Now, try writhing that by hand with three lazy argument 
and 6 places each that they could get evaluated for the first time. That 
would be a cake walk for a code generator and a nightmare for a programmer.



More information about the Digitalmars-d mailing list