www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - [D2] How to not full closure?

reply Frank Benoit <keinfarbton googlemail.com> writes:
On Nov 27 2007 in this NG, there was this thread "How to not full closure?"
See: 
http://www.digitalmars.com/d/archives/digitalmars/D/Howto_not_Full_closure_62508.html#N62542

For me, this is still a problem i see in using D2.
E.g. when i pass a delegate as a search criteria to a containers find 
function, the triggered heap allocation can destroy all of the 
performance. Even worse, i cannot manually delete the stack frame.
Imagine this function is called in a loop!

So this still is a D2 show stopper for me. Delegates are a very 
important D feature. Full closures remove delegates for performance 
critical code, without giving an alternative.

Please give this a high priority.
Jul 13 2008
parent reply davidl <davidl 126.com> writes:
在 Mon, 14 Jul 2008 01:15:26 +0800,Frank Benoit  
<keinfarbton googlemail.com> 写道:

 On Nov 27 2007 in this NG, there was this thread "How to not full  
 closure?"
 See:  
 http://www.digitalmars.com/d/archives/digitalmars/D/Howto_not_Full_closure_62508.html#N62542

 For me, this is still a problem i see in using D2.
 E.g. when i pass a delegate as a search criteria to a containers find  
 function, the triggered heap allocation can destroy all of the  
 performance. Even worse, i cannot manually delete the stack frame.
 Imagine this function is called in a loop!

 So this still is a D2 show stopper for me. Delegates are a very  
 important D feature. Full closures remove delegates for performance  
 critical code, without giving an alternative.

 Please give this a high priority.

it's better to introduce a new keyword, closure. there on heap: closure t = { // my closure return 3; } on stack: delegate t = { retirm 3; } -- 使用 Opera 革命性的电子邮件客户程序: http://www.opera.com/mail/
Jul 13 2008
next sibling parent reply Mike <vertex gmx.at> writes:
On Mon, 14 Jul 2008 04:39:58 +0200, davidl <davidl 126.com> wrote:

 it's better to introduce a new keyword, closure.

 there

 on heap:
 closure t = {
    // my closure
    return 3;
 }

 on stack:
 delegate t = {
    retirm 3;
 }

Wouldn't it suffice to overload the new keyword? heap: delegate t = new { return 3; } stack: delegate t = { return 3; } That way it could work with delegate literals too: int b = 3; foo(new { return b; }); -Mike -- Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
Jul 14 2008
next sibling parent reply downs <default_357-line yahoo.de> writes:
Mike wrote:
 On Mon, 14 Jul 2008 04:39:58 +0200, davidl <davidl 126.com> wrote:
 
 it's better to introduce a new keyword, closure.

 there

 on heap:
 closure t = {
    // my closure
    return 3;
 }

 on stack:
 delegate t = {
    retirm 3;
 }

Wouldn't it suffice to overload the new keyword? heap: delegate t = new { return 3; } stack: delegate t = { return 3; } That way it could work with delegate literals too: int b = 3; foo(new { return b; }); -Mike

For what it's worth, I like that solution a lot.
Jul 14 2008
parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"downs" <default_357-line yahoo.de> wrote in message 
news:g5fs5j$p0d$1 digitalmars.com...

 Wouldn't it suffice to overload the new keyword?

 heap:

 delegate t = new { return 3; }

 stack:

 delegate t = { return 3; }

 That way it could work with delegate literals too:

 int b = 3;
 foo(new { return b; });

 -Mike

For what it's worth, I like that solution a lot.

Seconded.
Jul 14 2008
prev sibling next sibling parent reply BCS <ao pathlink.com> writes:
Reply to mike,

 On Mon, 14 Jul 2008 04:39:58 +0200, davidl <davidl 126.com> wrote:
 
 it's better to introduce a new keyword, closure.
 
 there
 
 on heap:
 closure t = {
 // my closure
 return 3;
 }
 on stack:
 delegate t = {
 retirm 3;
 }

heap: delegate t = new { return 3; } stack: delegate t = { return 3; } That way it could work with delegate literals too: int b = 3; foo(new { return b; }); -Mike

I like it. a few questions: Would it only work with literals? what about nested functions? I have always thought that delegates should be able to be scope on anything you want: struct Foo { int bar; } Foo* f = new Foo; f.bar = 0; auto inc = f.new { this.bar++; } inc(); assert (f.bar==1); or even: int i = 5; auto times = i.new (int j){return this*j;} i=6; assert(times(i) == 30);
Jul 14 2008
parent reply bearophile <bearophileHUGS lycos.com> writes:
BCS:
 Wouldn't it suffice to overload the new keyword?
 heap:
 delegate t = new { return 3; }
 stack:
 delegate t = { return 3; }


Generally in D the default behavior must be the safer one, in this situation it means the heap version... Bye, bearophile
Jul 14 2008
parent BCS <ao pathlink.com> writes:
Reply to bearophile,

 Reply to mike,

 Wouldn't it suffice to overload the new keyword?
 heap:
 delegate t = new { return 3; }
 stack:
 delegate t = { return 3; }


situation it means the heap version...

but "is heap allocation always safe?"
Jul 14 2008
prev sibling next sibling parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Koroskin Denis" <2korden gmail.com> wrote in message 
news:op.ueaoscr8enyajd proton.creatstudio.intranet...
 Shouldn't it be heap-allocated by default? I prefer scope keywork reuse :)

You have a point there. And I think you may have something with using 'scope' to indicate nested functions whose stack frames are not to be heap-allocated. It goes along with scope classes nicely. You wouldn't be able to return a scope delegate, and it makes sense -- "this delegate only works in this scope. When the scope leaves, the delegate is no longer valid." Adding "scope" also makes it possible for the compiler to check that you don't do stupid things statically, at least in many cases.
Jul 14 2008
parent reply Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
Jarrett Billingsley wrote:
 "Koroskin Denis" <2korden gmail.com> wrote in message 
 news:op.ueaoscr8enyajd proton.creatstudio.intranet...
 Shouldn't it be heap-allocated by default? I prefer scope keywork reuse :)

You have a point there. And I think you may have something with using 'scope' to indicate nested functions whose stack frames are not to be heap-allocated. It goes along with scope classes nicely. You wouldn't be able to return a scope delegate, and it makes sense -- "this delegate only works in this scope. When the scope leaves, the delegate is no longer valid." Adding "scope" also makes it possible for the compiler to check that you don't do stupid things statically, at least in many cases.

I think Walter's solution ("using 'scope' to tag function parameters that do not escape") may be even better. It doesn't add new syntax to literals, is statically verifiable more "locally", and may have other uses other than for delegates. -- Bruno Medeiros - Software Developer, MSc. in CS/E graduate http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Jul 27 2008
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Bruno Medeiros:
 I think Walter's solution ("using 'scope' to tag function parameters 
 that do not escape") may be even better. It doesn't add new syntax to 
 literals, is statically verifiable more "locally", and may have other 
 uses other than for delegates.

So to pass a lambda without closure you have to write something like this? foo(scope (int x){return x*x;}); Bye, bearophile
Jul 27 2008
parent Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
bearophile wrote:
 Bruno Medeiros:
 I think Walter's solution ("using 'scope' to tag function parameters 
 that do not escape") may be even better. It doesn't add new syntax to 
 literals, is statically verifiable more "locally", and may have other 
 uses other than for delegates.

So to pass a lambda without closure you have to write something like this? foo(scope (int x){return x*x;}); Bye, bearophile

I said parameters, not arguments. You'd declared the function like this: void foo(scope int delegate(int) dg) { the function call would remain the same: foo((int x){return x*x;}); Seems a better solution, at least at first sight, haven't though much about it. -- Bruno Medeiros - Software Developer, MSc. in CS/E graduate http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Jul 30 2008
prev sibling parent reply Sean Kelly <sean invisibleduck.org> writes:
== Quote from Bruno Medeiros (brunodomedeiros+spam com.gmail)'s article
 Jarrett Billingsley wrote:
 "Koroskin Denis" <2korden gmail.com> wrote in message
 news:op.ueaoscr8enyajd proton.creatstudio.intranet...
 Shouldn't it be heap-allocated by default? I prefer scope keywork reuse :)

You have a point there. And I think you may have something with using 'scope' to indicate nested functions whose stack frames are not to be heap-allocated. It goes along with scope classes nicely. You wouldn't be able to return a scope delegate, and it makes sense -- "this delegate only works in this scope. When the scope leaves, the delegate is no longer valid." Adding "scope" also makes it possible for the compiler to check that you don't do stupid things statically, at least in many cases.

that do not escape") may be even better. It doesn't add new syntax to literals, is statically verifiable more "locally", and may have other uses other than for delegates.

Tagging the stuff that doesn't escape isn't backwards-compatible with D 1.0, where non-escaping is the default. Not that we don't already have some pointless portability issues from D 1.0 to D 2.0, but I'd think it would be desirable to not add more. Sean
Jul 27 2008
parent reply Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
Sean Kelly wrote:
 == Quote from Bruno Medeiros (brunodomedeiros+spam com.gmail)'s article
 Jarrett Billingsley wrote:
 "Koroskin Denis" <2korden gmail.com> wrote in message
 news:op.ueaoscr8enyajd proton.creatstudio.intranet...
 Shouldn't it be heap-allocated by default? I prefer scope keywork reuse :)

'scope' to indicate nested functions whose stack frames are not to be heap-allocated. It goes along with scope classes nicely. You wouldn't be able to return a scope delegate, and it makes sense -- "this delegate only works in this scope. When the scope leaves, the delegate is no longer valid." Adding "scope" also makes it possible for the compiler to check that you don't do stupid things statically, at least in many cases.

that do not escape") may be even better. It doesn't add new syntax to literals, is statically verifiable more "locally", and may have other uses other than for delegates.

Tagging the stuff that doesn't escape isn't backwards-compatible with D 1.0, where non-escaping is the default. Not that we don't already have some pointless portability issues from D 1.0 to D 2.0, but I'd think it would be desirable to not add more. Sean

D 2.0 vs 1.0 is not like Java 1.5 vs Java 1.4, or C# 2 vs. C# 3. D is still very "experimental" and very under development, and, for better or worse, that makes the differences between D 2.0 and 1.0 many, profound, and ever-increasing. The "worse" part is that it makes it very hard to maintain compatibility, perhaps even unpractical at all? I wish there wasn't a need or desire to maintain 1.0 compatibility, and people would move to 2.0. The sole key to this being Tango of course. I understand you have good motives for not moving to 2.0 yet, but I hope those can solved quite sooner rather later. The D community has allways been divided in two camps, but never has the "rift" been so wide and hurtful as now. :/ -- Bruno Medeiros - Software Developer, MSc. in CS/E graduate http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Jul 30 2008
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Bruno Medeiros" wrote
 I wish there wasn't a need or desire to maintain 1.0 compatibility, and 
 people would move to 2.0. The sole key to this being Tango of course. I 
 understand you have good motives for not moving to 2.0 yet, but I hope 
 those can solved quite sooner rather later. The D community has allways 
 been divided in two camps, but never has the "rift" been so wide and 
 hurtful as now. :/

We have tried. D2 has too many blocker bugs for Tango to work properly, otherwise, there would be a D2 port. But even if this did happen, there is no way that Tango would move to an as-yet-unreleased compiler and abandon efforts on D1. And most likely, D1 Tango would continue to exist because some people simply don't like const. I plan to move to D2 as soon as Tango can build with it. -Steve
Jul 30 2008
parent Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
Bill Baxter wrote:
 On Thu, Jul 31, 2008 at 8:01 AM, Steven Schveighoffer
 <schveiguy yahoo.com> wrote:
 "Bruno Medeiros" wrote
 I wish there wasn't a need or desire to maintain 1.0 compatibility, and
 people would move to 2.0. The sole key to this being Tango of course. I
 understand you have good motives for not moving to 2.0 yet, but I hope
 those can solved quite sooner rather later. The D community has allways
 been divided in two camps, but never has the "rift" been so wide and
 hurtful as now. :/

otherwise, there would be a D2 port. But even if this did happen, there is no way that Tango would move to an as-yet-unreleased compiler and abandon efforts on D1. And most likely, D1 Tango would continue to exist because some people simply don't like const. I plan to move to D2 as soon as Tango can build with it.

Is there a list of these Tango blocker bugs somewhere? Perhaps the list should be put into bugzilla as a meta-bug that references all the relevant issues in bugzilla. I have to believe that if Walter had a clear idea of what the bugs blocking Tango were, that he would prioritize them and wipe them out within a release or two. --bb

I'm not so sure Walter would fix the bugs that promptly, for starters there could be issues in which there is a debate whether the issue is actually a bug or a (possibly breaking) enhancement request, which Walter seems more reluctant to "fix". And I recall Sean mentioning several such issues (for example the one about a way to specify scope delegates, to prevent closure heap allocation) Such list would be nice to have nonetheless, at least for people to have a general idea of what's missing for D2.0 to be considered a viable target for Tango. And perhaps so that other Tango users would know the issues and exert more pressure to Walter to fix them. -- Bruno Medeiros - Software Developer, MSc. in CS/E graduate http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Aug 04 2008
prev sibling parent reply Frank Benoit <keinfarbton googlemail.com> writes:
Mike schrieb:
 On Mon, 14 Jul 2008 04:39:58 +0200, davidl <davidl 126.com> wrote:
 
 it's better to introduce a new keyword, closure.

 there

 on heap:
 closure t = {
    // my closure
    return 3;
 }

 on stack:
 delegate t = {
    retirm 3;
 }

Wouldn't it suffice to overload the new keyword? heap: delegate t = new { return 3; } stack: delegate t = { return 3; } That way it could work with delegate literals too: int b = 3; foo(new { return b; }); -Mike

I think the problem here is, new says that it will force a heap allocation for its call. But the heap allocation shall not happen per delegate, it shall only happen once for the surrounding stack frame if it contains at least one heap allocated delegate. hm, is it understandable what i mean by this ? :)
Jul 14 2008
parent BCS <ao pathlink.com> writes:
Reply to Frank,

 Mike schrieb:
 
 On Mon, 14 Jul 2008 04:39:58 +0200, davidl <davidl 126.com> wrote:
 
 it's better to introduce a new keyword, closure.
 
 there
 
 on heap:
 closure t = {
 // my closure
 return 3;
 }
 on stack:
 delegate t = {
 retirm 3;
 }

heap: delegate t = new { return 3; } stack: delegate t = { return 3; } That way it could work with delegate literals too: int b = 3; foo(new { return b; }); -Mike

allocation for its call. But the heap allocation shall not happen per delegate, it shall only happen once for the surrounding stack frame if it contains at least one heap allocated delegate. hm, is it understandable what i mean by this ? :)

Yes, I understand it. (FWIW)
Jul 14 2008
prev sibling next sibling parent "Koroskin Denis" <2korden gmail.com> writes:
On Mon, 14 Jul 2008 19:35:53 +0400, Mike <vertex gmx.at> wrote:

 On Mon, 14 Jul 2008 04:39:58 +0200, davidl <davidl 126.com> wrote:

 it's better to introduce a new keyword, closure.

 there

 on heap:
 closure t = {
    // my closure
    return 3;
 }

 on stack:
 delegate t = {
    retirm 3;
 }

Wouldn't it suffice to overload the new keyword? heap: delegate t = new { return 3; } stack: delegate t = { return 3; } That way it could work with delegate literals too: int b = 3; foo(new { return b; }); -Mike

Shouldn't it be heap-allocated by default? I prefer scope keywork reuse :)
Jul 14 2008
prev sibling next sibling parent Mike <vertex gmx.at> writes:
On Mon, 14 Jul 2008 21:31:47 +0200, Jarrett Billingsley  
<kb3ctd2 yahoo.com> wrote:

 You have a point there.  And I think you may have something with using
 'scope' to indicate nested functions whose stack frames are not to be
 heap-allocated.  It goes along with scope classes nicely.  You wouldn't  
 be
 able to return a scope delegate, and it makes sense -- "this delegate  
 only
 works in this scope.  When the scope leaves, the delegate is no longer
 valid."

 Adding "scope" also makes it possible for the compiler to check that you
 don't do stupid things statically, at least in many cases.

I agree, and bearophile's point is a good one, too (meaning D should do the safe thing by default). I like the idea of new, though, because it indicates that new memory is being allocated on the heap. So I'd like this: int b = 4; auto heap = new { return b; } auto stack = scope { return b; } b++; assert(heap() == 4); assert(stack() == 5); And "new" being the default it's legal to omit it: auto heap = { ... } auto stack = scope { ... } -Mike -- Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
Jul 14 2008
prev sibling parent reply "Bill Baxter" <wbaxter gmail.com> writes:
On Thu, Jul 31, 2008 at 8:01 AM, Steven Schveighoffer
<schveiguy yahoo.com> wrote:
 "Bruno Medeiros" wrote
 I wish there wasn't a need or desire to maintain 1.0 compatibility, and
 people would move to 2.0. The sole key to this being Tango of course. I
 understand you have good motives for not moving to 2.0 yet, but I hope
 those can solved quite sooner rather later. The D community has allways
 been divided in two camps, but never has the "rift" been so wide and
 hurtful as now. :/

We have tried. D2 has too many blocker bugs for Tango to work properly, otherwise, there would be a D2 port. But even if this did happen, there is no way that Tango would move to an as-yet-unreleased compiler and abandon efforts on D1. And most likely, D1 Tango would continue to exist because some people simply don't like const. I plan to move to D2 as soon as Tango can build with it.

Is there a list of these Tango blocker bugs somewhere? Perhaps the list should be put into bugzilla as a meta-bug that references all the relevant issues in bugzilla. I have to believe that if Walter had a clear idea of what the bugs blocking Tango were, that he would prioritize them and wipe them out within a release or two. --bb
Jul 30 2008
next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Bill Baxter" wrote
 On Thu, Jul 31, 2008 at 8:01 AM, Steven Schveighoffer
 <schveiguy yahoo.com> wrote:
 "Bruno Medeiros" wrote
 I wish there wasn't a need or desire to maintain 1.0 compatibility, and
 people would move to 2.0. The sole key to this being Tango of course. I
 understand you have good motives for not moving to 2.0 yet, but I hope
 those can solved quite sooner rather later. The D community has allways
 been divided in two camps, but never has the "rift" been so wide and
 hurtful as now. :/

We have tried. D2 has too many blocker bugs for Tango to work properly, otherwise, there would be a D2 port. But even if this did happen, there is no way that Tango would move to an as-yet-unreleased compiler and abandon efforts on D1. And most likely, D1 Tango would continue to exist because some people simply don't like const. I plan to move to D2 as soon as Tango can build with it.

Is there a list of these Tango blocker bugs somewhere? Perhaps the list should be put into bugzilla as a meta-bug that references all the relevant issues in bugzilla.

That is a good idea.
 I have to believe
 that if Walter had a clear idea of what the bugs blocking Tango were,
 that he would prioritize them and wipe them out within a release or
 two.

Some of them might be on the fuzzy edge between "bugs" and "enhancements" :) But they need to be addressed in order for Tango to build regardless. -Steve
Jul 30 2008
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Bill Baxter" wrote
 On Thu, Jul 31, 2008 at 8:01 AM, Steven Schveighoffer
 "Bruno Medeiros" wrote
 I wish there wasn't a need or desire to maintain 1.0 compatibility, and
 people would move to 2.0. The sole key to this being Tango of course. I
 understand you have good motives for not moving to 2.0 yet, but I hope
 those can solved quite sooner rather later. The D community has allways
 been divided in two camps, but never has the "rift" been so wide and
 hurtful as now. :/

We have tried. D2 has too many blocker bugs for Tango to work properly, otherwise, there would be a D2 port. But even if this did happen, there is no way that Tango would move to an as-yet-unreleased compiler and abandon efforts on D1. And most likely, D1 Tango would continue to exist because some people simply don't like const. I plan to move to D2 as soon as Tango can build with it.

Is there a list of these Tango blocker bugs somewhere? Perhaps the list should be put into bugzilla as a meta-bug that references all the relevant issues in bugzilla. I have to believe that if Walter had a clear idea of what the bugs blocking Tango were, that he would prioritize them and wipe them out within a release or two.

Added bugzilla number 2267 http://d.puremagic.com/issues/show_bug.cgi?id=2267 -Steve
Aug 04 2008