Copying a delegate

Jonathan M Davis jmdavisProg at gmx.com
Sun Sep 19 19:18:34 PDT 2010


On Sunday 19 September 2010 17:13:14 Stewart Gordon wrote:
> On 19/09/2010 04:35, Jonathan M Davis wrote:
> <snip>
> 
> > That doesn't work because you're just copying the pointer. Is there a way
> > to actually do a deep copy of the delegate? I can see why this would be
> > problematic if the delegate had reference types in its scope (since
> > presumably, they'd have to be shallow copied unless you somehow had the
> > equivalent of a copy constructor or postblit constructor for delegates),
> > but even the ability to a do a shallow copy would be better than
> > nothing. Is there any way to do that, or am I out of luck?
> 
> You mean to duplicate whatever the delegate's context pointer points to?
> 
> The trouble is that the context pointer could point to either an object
> or a stack frame.  Any code to duplicate a delegate on this basis would
> need to consider both possibilities.  Moreover, a class may or may not
> provide a dup method, and there's no predictable vtbl slot for it.
> Things get even more complicated when you realise that occasionally
> there may be an object allocated on the stack.
> 
> As such, this would be a complex feature, and IMO unlikely to be
> implemented.  I can't even think of any real practical use for it.  Can
> you?
> 
> Stewart.

Most definitely yes, I can think of a purpose for it, though I can certainly see 
why it may be unreasonable to have it. The issue is the save property for 
forward ranges. For it to work properly, it must be able to copy all of the 
state related to iteration. So, any reference types must either be unrelated to 
saving the iteration state, or they must be deep copied. It can be quite useful 
to use functions are delegates to generate a range. So, when you call 
popFront(), the internal function pointer or delegate is used to generate the 
next element in the range. The problem is that there is no way to do a deep copy 
of a function pointer or a delegate. The function pointed to could access 
globals or static state unless it's pure (and it can be quite hard to have a 
pure function which is useful enough to be used in a such a situation). The 
delegate by definition has context which is not going to be copied. So, any 
functon pointer or delegate that you have must refer to a function which is 
logically pure, otherwise any algorithm that relies on save is not going to work 
correctly. This makes it impossible to use delegates which use their own 
internal state or global state to help determine what the next element would be. 
Even being able to do a shallow copy of a delegate (so, doing a shallow copy of 
its context) would increase what you could do with such a delegate, though a 
deep copy is what you'd really need.

You can get around the problem by using functors instead of delegates, but 
functors are way more unweildy and much less pleasant to create. With delegates, 
you can use lambda functions which are far more pleasant.

So, I can understand why it's probably infeasible to get a deep copy of a 
delegate, and why it would be difficult in not totally unreasonable to get a 
shallow copy of one, but it would definitely be useful if you could.

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list