Delegates

Pragma ericanderton at yahoo.removeme.com
Fri Jan 19 07:27:26 PST 2007


Robin Allen wrote:
> I'm trying to figure out delegates. From what I can see, they're intended to be what other languages call closures?
> 
> So, say I wanted to write some functions for signal processing. I'd define a Wave type as a function of time, like this:
> 
> alias float delegate(float) Wave;
> 
> and a function to return a sine wave of a specified frequency like this:
> 
> Wave sine(float freq)
> {
>   return delegate(float t) { return std.math.sin(2*std.math.PI*t); };
> }
> 
> When I realised this didn't work at all, I cut back the code to something very basic and realised that even this doesn't work:
> 
> Wave constant(float value)
> {
>   return delegate(float t) { return value; }
> }
> 
> Wave w0 = constant(6);
> float x = w0(42); // x is now 42, not 6
> 
> But it does work if I change the function to:
> 
> Wave constant(float value)
> {
>   float _value = value;
>   return delegate(float t) { return _value;}
> }
> 
> I hesitate to cry "bug" because there's quite a large possibility that I don't understand delegates at all, but it seems a little weird.
> 
> Another oddity I found, and which I hope someone could explain, is:
> 
> Wave ramp(float start, float end, float length)
> {
> 	float _start = start;
> 	float _end = end;
> 	float _length = length;
> 	
> 	return delegate(float t)
> 	{
> 		writefln("%f %f",t,_length);
> 		float fact = math.remainder(t, _length);
> 		return _start + (_end-_start)*fact;
> 	};
> }
> 
> The above function's behaviour changes if I just commment out the writefln line. That can't be right!

Like Fritz said, returning an anonymous delegate is never a good idea.  The 'delegate' created is really a function 
bound to the current chunk of the call stack at the point of creation - so once you return it, it's invalid.

-- 
- EricAnderton at yahoo


More information about the Digitalmars-d-learn mailing list