August 18, 2006 Re: The future of lambda delegates | ||||
---|---|---|---|---|
| ||||
Posted in reply to kris | kris wrote: > xs0 wrote: >> Well, to me it seems that anything the compiler will try to do automatically will be wrong (or at least needlessly slow) in many cases. And a lot of the problem seems to be simply that one can't attach storage to a delegate without creating a whole class/struct, and doing that is too verbose to be used easily/often. >> >> So, why not simply have some syntax sugar for that? >> >> int delegate() fibs() >> { >> int a=0, b=1; >> return delegate with(a,b) { // it takes a and b with it >> ... >> } >> } > > Nice, but the problem with that is as follows: > > When passing such a delegate as an argument, you don't know whether it'll be used in a synchronous or asynchronous manner. Are you sure you don't know? I can't think of a case where I'd be in doubt.. > So, perhaps you choose the safe route and assume worst-case. That's cool, but if you choose best case instead (because you 'know' usage is synchronous) then you leave yourself open to nasty issues if that callee is ever changed. Think about passing a delegate to a third-party lib? The contract is weak, and therefore fragile. That's why we'd suggested an extension to the type system instead (which also has some problems). Well, I think it's not as big a problem realistically.. When you provide a delegate you need to know what its purpose is and I think that is something very unlikely to change. The two main types of delegates seem to be callbacks and specific operations for generic algorithms. I don't see how a library update would change the contract between those two. > The other thing that Mik noted is that the entire frame should be on the heap; not just part of it (for performance reasons) What performance reasons? I read this entire thread and still have no idea how copying more/all of the frame could/would be faster.. > , and taking a snapshot copy of the scope (or part thereof) does not work at all, since there could be self-references, pointers, whatever, in there. It seems you have to flip the entire frame into the heap. The semantics are clear - the current values of the with() variables get copied at the point where the delegate literal becomes "instantiated"; whatever you put there is up to you.. xs0 |
August 18, 2006 Re: The future of lambda delegates | ||||
---|---|---|---|---|
| ||||
Posted in reply to xs0 | xs0 wrote: > Mikola Lysenko wrote: >> [snip] >> Any thoughts or comments? > > Well, to me it seems that anything the compiler will try to do automatically will be wrong (or at least needlessly slow) in many cases. And a lot of the problem seems to be simply that one can't attach storage to a delegate without creating a whole class/struct, and doing that is too verbose to be used easily/often. > > So, why not simply have some syntax sugar for that? > > int delegate() fibs() > { > int a=0, b=1; > return delegate with(a,b) { // it takes a and b with it > ... > } > } > > Which would become exactly what you proposed. > > > xs0 Would the instances of a & b of the fibs function be the same as the ones in the delegate? In other words, does the "with(a,b)" create a heap copy of a & b, for the delegate to use, or does it cause the original "int a=0, b=1;" to be heap allocated? -- Bruno Medeiros - MSc in CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D |
August 18, 2006 Re: The future of lambda delegates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bruno Medeiros | Bruno Medeiros wrote:
> xs0 wrote:
>> Mikola Lysenko wrote:
>>> [snip]
>>> Any thoughts or comments?
>>
>> Well, to me it seems that anything the compiler will try to do automatically will be wrong (or at least needlessly slow) in many cases. And a lot of the problem seems to be simply that one can't attach storage to a delegate without creating a whole class/struct, and doing that is too verbose to be used easily/often.
>>
>> So, why not simply have some syntax sugar for that?
>>
>> int delegate() fibs()
>> {
>> int a=0, b=1;
>> return delegate with(a,b) { // it takes a and b with it
>> ...
>> }
>> }
>>
>> Which would become exactly what you proposed.
>>
>>
>> xs0
>
> Would the instances of a & b of the fibs function be the same as the ones in the delegate? In other words, does the "with(a,b)" create a heap copy of a & b, for the delegate to use, or does it cause the original "int a=0, b=1;" to be heap allocated?
A heap copy is created at the point in code where the delegate is "evaluated". For example, the above case would function exactly the same as the following:
int delegate() fibs()
{
int a=0, b=1;
auto result = delegate with(a,b) {
...
}
a = 5000;
b = -1;
return result;
}
because it would become this behind the scenes:
class _anonymousclass123 // more probably struct
{
int a, b;
this(int a, int b) {
this.a=a; this.b=b;
}
int _anonymousfunc() {
...
}
}
int delegate() fibs()
{
int a=0, b=1;
auto result = &((new _anonymousclass123(a, b))._anonymousfunc);
a = 5000;
b = -1;
return result;
}
Of course, the compiler is free to allocate the fibs()'s a and b on the heap, if it determines the result is the same (it's potentially better because less stack is used), though I don't think it would actually matter in any realistic case..
xs0
|
August 24, 2006 Re: The future of lambda delegates | ||||
---|---|---|---|---|
| ||||
Posted in reply to BCS | BCS wrote:
> because this is so much slower, I would hate to see it happen silently. Having a function use a heap-frame just because I add a delegate could cause some hard to track down performance hits. I would advocate making the escaping delegate illegal unless the code explicitly says to put /part/ or all of the frame on the heap.
Wow, the concept of putting only *part* of the frame on the heap really blew my mind. It suggests the following syntax:
void foo() {
int a; // on stack
heap { // all variables in this scope on the heap
...stuff...
}
}
|
Copyright © 1999-2021 by the D Language Foundation