digitalmars.D - Nested functions should be exempt from sequential visibility rules
- Nick Sabalausky (13/13) Apr 02 2012 Regarding this:
- James Miller (5/7) Apr 02 2012 Off Topic: In Gmail, it applied both labels to the one email, which is c...
- Nick Sabalausky (50/52) Apr 03 2012 Personally, I don't much care ATM. Either way has it's pros and cons:
- deadalnix (2/15) Apr 03 2012 This is a +1 .
- Don Clugston (21/34) Apr 03 2012 This is asking for a complicated special case. In global scope, order of...
- Nick Sabalausky (62/75) Apr 03 2012 Does being inside a function really make the type deduction any harder (...
- Don Clugston (15/45) Apr 03 2012 Yes, it's different. In the second case, X is entirely determined at
- Walter Bright (4/6) Apr 05 2012 I agree with Don. And in the end, is a morass of complexity worth it to ...
- Timon Gehr (7/49) Apr 03 2012 I come to a different conclusion. If only function declarations are
- Don Clugston (8/48) Apr 03 2012 I don't see a way to just declare it as "illegal". How would you detect
- Michel Fortin (17/46) Apr 03 2012 You're right Don, it shouldn't be illegal. But it could be part of the
- Timon Gehr (3/7) Apr 03 2012 Since only function declarations are immune to ordering rules, b cannot
- Don Clugston (3/12) Apr 03 2012 But there could be another function a() which is below x, and which b()
- Timon Gehr (2/15) Apr 03 2012 This scenario can be forbidden conservatively.
- Don Clugston (2/18) Apr 03 2012 How?
- Timon Gehr (7/26) Apr 03 2012 Don't allow forward referencing function a() if there is an intervening
- Nick Sabalausky (37/44) Apr 03 2012 We don't *have* to go the route of allowing nested functions to access
- Don Clugston (7/54) Apr 03 2012 But it's the same. If you can forward reference a function, you can also...
- Timon Gehr (11/24) Apr 03 2012 This is the right way to work around this issue. It works now and does
- Nick Sabalausky (9/15) Apr 03 2012 That's a very simple workaround (albiet unintuitive - unless I'm just to...
- Timon Gehr (14/32) Apr 03 2012 Your proposal is basically to allow a local function to forward
- Martin Nowak (3/16) Apr 03 2012 I'd argue it shouldn't work, but it'd require copying the scope.
- Xinok (46/64) Apr 04 2012 Currently, it prints 365. But remove the commented line, and it
- bearophile (15/20) Apr 03 2012 What about static nested functions? This seems a simpler
- Don Clugston (18/31) Apr 04 2012 The most flexible method is to declare a local, nested struct. Any
- Walter Bright (3/6) Apr 05 2012 Thanks, Don. I didn't think of this, and it's an awesome solution. Can y...
- stas (6/9) Oct 10 2012 If D had a notion of pure pure functions - pure functions without
Regarding this: http://d.puremagic.com/issues/show_bug.cgi?id=790 I submit that nested functions should be exempt from the usual sequential visibility rules. (Therefore, mutually recursive nested functions would become possible.) Or at the very *least*, this horrific C-like workaround should be possible: void foo() { void b(); void a() {...}; void b() {...}; } ...Flame away! ;)
Apr 02 2012
Sorry, I didn't mean this to go into "D.announce". Reposting in the proper place... Can this one be deleted?Off Topic: In Gmail, it applied both labels to the one email, which is cool :D. Otherwise I think that the C-like workaround should be ok, the issue is with closures, what values should be visible to the closures? -- James Miller
Apr 02 2012
"James Miller" <james aatch.net> wrote in message news:mailman.1324.1333434077.4860.digitalmars-d puremagic.com...[...]the issue is with closures, what values should be visible to the closures?Personally, I don't much care ATM. Either way has it's pros and cons: A. Same as right now: The nested function can only access variables defined before it. Only difference is that it can *also* access "sibling" nested functions that are defined before *or* after. The benefit is that there's minimal change to the current "sequential visibility". B. Let nested funcs access *any* "sibling" symbol whether defined before or after. Presumably, the nested func would not be *callable* until after all the sibling symbols it accesses have been declared. The downside is that, I suspect, this might be more work to implement. The benefits are that it provides more flexibility and is more consistent with module-level declarations. That latter benefit would be import for code like this: void main() { mixin(import("script.d")); } I guess I would lean more towards "B", but it is a bigger change and I realize bigger changes meet bigger resistance at this point. So I'd be content either way because what's *more* important here is we ditch the (seemingly) silly restriction of "no mutually recursive nested funcs". 'Course, another approach would be to just for the compiler to treat this: void foo() { /+ code 1 +/ void a() {...}; /+ code 2 +/ void b() {...}; /+ code 3 +/ } Like this: void foo() { void delegate() a; void delegate() b; /+ code 1 +/ a = () {...}; /+ code 2 +/ b = () {...}; /+ code 3 +/ // Except that, naturally, a and b cannot // be re-assigned by the programmer, // and foo itself cannot access a or b // before the "a = ...;" and "b = ...;" lines // respectively. } This maybe makes the most sense, because nested funcs and anon-funcs-assigned-to-a-variable *are* so very similar anyway. But then again, this comes with the downside of "void main() { mixin(import("script.d")); }" causing strange semantics inside 'script.d'...but I guess such strange semantics in 'script.d' would be the case even without any nested funcs involved. Actually, this might be equivalent to approach "A" above.
Apr 03 2012
Le 03/04/2012 07:38, Nick Sabalausky a écrit :Regarding this: http://d.puremagic.com/issues/show_bug.cgi?id=790 I submit that nested functions should be exempt from the usual sequential visibility rules. (Therefore, mutually recursive nested functions would become possible.) Or at the very *least*, this horrific C-like workaround should be possible: void foo() { void b(); void a() {...}; void b() {...}; } ...Flame away! ;)This is a +1 .
Apr 03 2012
On 03/04/12 07:38, Nick Sabalausky wrote:Regarding this: http://d.puremagic.com/issues/show_bug.cgi?id=790 I submit that nested functions should be exempt from the usual sequential visibility rules. (Therefore, mutually recursive nested functions would become possible.) Or at the very *least*, this horrific C-like workaround should be possible: void foo() { void b(); void a() {...}; void b() {...}; } ...Flame away! ;)This is asking for a complicated special case. In global scope, order of declarations doesn't matter. In function scope, order of declarations always matters. If you have type inference of function returns, things can get nasty: void foo() { auto b() { return a(); } X x = whatever; auto a() { return x; } } Now b actually depends on the declaration of x. So it's not enough to say that only function declarations are immune to ordering rules. Furthermore, any declaration before x, which calls b(), is using x even though x hasn't been initialized (or even declared) yet. Suddenly all kinds of horrible situations become possible, which could never happen before. In general, allowing forward references inside a function is far, far more difficult than in global scope. There are very many more special cases. Allowing it in global scope is quite complicated enough. You can always use a delegate, if you want recursive nested functions.
Apr 03 2012
"Don Clugston" <dac nospam.com> wrote in message news:jlecab$9gh$1 digitalmars.com...If you have type inference of function returns, things can get nasty: void foo() { auto b() { return a(); } X x = whatever; auto a() { return x; } } Now b actually depends on the declaration of x. So it's not enough to say that only function declarations are immune to ordering rules.Does being inside a function really make the type deduction any harder (or different?) than this?: auto b() { return a(); } enum X x = whatever; auto a() { return x; }Furthermore, any declaration before x, which calls b(), is using x even though x hasn't been initialized (or even declared) yet. Suddenly all kinds of horrible situations become possible, which could never happen before.(Don't know if this makes any sence, but I'm throwing it out there...) Suppose we did the approach I mentioned elsewhere in this thread: "the compiler rewrites nested func decls as delegate vars and anon funcs". Suppose we also use the rule: "A nested func is not *callable* (by either the parent function *or* another nested function) until after (ie "further down in the code") all the sibling symbols it accesses have been declared." If it's reasonable for type deduction to happen before all this (I have no idea how realistic that is), then with your example, the compiler first deduces the types just like it would outside a function: void foo() { X b() { return a(); } X x = whatever; X a() { return x; } } Then it gets rewritten: void foo() { delegate X() b; delegate X() a; b = X() { return a(); } X x = whatever; a = X() { return x; } } This would now be flagged as an error because "b" is calling "a" before (ie "earlier in the code than") all of the symbols "a" accesses (namely "x") have been declared. The following would also be an error for the same reason: void foo() { auto b() { return a(); } X w = b(); X x = whatever; auto a() { return x; } } However, this would still be perfectly ok: void foo() { X x = whatever; auto b() { return a(); } auto a() { return x; } } Because it turns into: void foo() { delegate X() b; delegate X() a; X x = whatever; b = X() { return a(); } a = X() { return x; } } And now, at the point in the code where "b" calls "a", everything "a" accesses (namely "x") has *already* been declared and inited. And of couse, "b" *can* call "a" because "a" is already declared way at the top.
Apr 03 2012
On 03/04/12 11:24, Nick Sabalausky wrote:"Don Clugston"<dac nospam.com> wrote in message news:jlecab$9gh$1 digitalmars.com...Yes, it's different. In the second case, X is entirely determined at compile time. If you have multiple declarations, there are no user-visible semantics which are order-dependent; the value of the expression is independent of its location in the file. This is not true of declarations inside a scope: eg, static int count = 0; int order() { ++count; return count; } int x = order(); int y = order(); assert(x == 1); assert(y == 2);If you have type inference of function returns, things can get nasty: void foo() { auto b() { return a(); } X x = whatever; auto a() { return x; } } Now b actually depends on the declaration of x. So it's not enough to say that only function declarations are immune to ordering rules.Does being inside a function really make the type deduction any harder (or different?) than this?: auto b() { return a(); } enum X x = whatever; auto a() { return x; }Difficult but doable, but I think you end up with a really funky rule. It's a morass of special cases.Furthermore, any declaration before x, which calls b(), is using x even though x hasn't been initialized (or even declared) yet. Suddenly all kinds of horrible situations become possible, which could never happen before.(Don't know if this makes any sence, but I'm throwing it out there...) Suppose we did the approach I mentioned elsewhere in this thread: "the compiler rewrites nested func decls as delegate vars and anon funcs". Suppose we also use the rule: "A nested func is not *callable* (by either the parent function *or* another nested function) until after (ie "further down in the code") all the sibling symbols it accesses have been declared."
Apr 03 2012
On 4/3/2012 2:56 AM, Don Clugston wrote:Difficult but doable, but I think you end up with a really funky rule. It's a morass of special cases.I agree with Don. And in the end, is a morass of complexity worth it to deal with one special case that is both unusual and has a reasonable workaround? I'd say no.
Apr 05 2012
On 04/03/2012 10:27 AM, Don Clugston wrote:On 03/04/12 07:38, Nick Sabalausky wrote:I come to a different conclusion. If only function declarations are immune to ordering rules, the above example is simply illegal. The example cannot be used to demonstrate incompleteness of the approach.Regarding this: http://d.puremagic.com/issues/show_bug.cgi?id=790 I submit that nested functions should be exempt from the usual sequential visibility rules. (Therefore, mutually recursive nested functions would become possible.) Or at the very *least*, this horrific C-like workaround should be possible: void foo() { void b(); void a() {...}; void b() {...}; } ...Flame away! ;)This is asking for a complicated special case. In global scope, order of declarations doesn't matter. In function scope, order of declarations always matters. If you have type inference of function returns, things can get nasty: void foo() { auto b() { return a(); } X x = whatever; auto a() { return x; } } Now b actually depends on the declaration of x. So it's not enough to say that only function declarations are immune to ordering rules.Furthermore, any declaration before x, which calls b(), is using x even though x hasn't been initialized (or even declared) yet. Suddenly all kinds of horrible situations become possible, which could never happen before. In general, allowing forward references inside a function is far, far more difficult than in global scope.If it is constrained enough, it shouldn't be more difficult.There are very many more special cases. Allowing it in global scope is quite complicated enough.It should be possible to leverage the efforts spent there.You can always use a delegate, if you want recursive nested functions.Templates are superior.
Apr 03 2012
On 03/04/12 12:32, Timon Gehr wrote:On 04/03/2012 10:27 AM, Don Clugston wrote:I don't see a way to just declare it as "illegal". How would you detect that situation in the general case? It's not easy. Y b() { ... } Y y = b(); X x = ... Prove that y doesn't depend on x.On 03/04/12 07:38, Nick Sabalausky wrote:I come to a different conclusion. If only function declarations are immune to ordering rules, the above example is simply illegal. The example cannot be used to demonstrate incompleteness of the approach.Regarding this: http://d.puremagic.com/issues/show_bug.cgi?id=790 I submit that nested functions should be exempt from the usual sequential visibility rules. (Therefore, mutually recursive nested functions would become possible.) Or at the very *least*, this horrific C-like workaround should be possible: void foo() { void b(); void a() {...}; void b() {...}; } ...Flame away! ;)This is asking for a complicated special case. In global scope, order of declarations doesn't matter. In function scope, order of declarations always matters. If you have type inference of function returns, things can get nasty: void foo() { auto b() { return a(); } X x = whatever; auto a() { return x; } } Now b actually depends on the declaration of x. So it's not enough to say that only function declarations are immune to ordering rules.
Apr 03 2012
On 2012-04-03 11:08:38 +0000, Don Clugston <dac nospam.com> said:On 03/04/12 12:32, Timon Gehr wrote:You're right Don, it shouldn't be illegal. But it could be part of the constrain. Let's rephrase Timon's idea like this: If two or more functions declarations are following each other with no other statement in between, then these two functions can call one another. That could allow overloading too, as long as the declarations are following each other directly. In fact, that'd probably be generalizable to templates, struct, class, and enum declarations too. Adjacent declarations would create some kind of island in the function's code where order of declaration does not matter. The island ends at the first non-declaration statement or local variable declaration, and a new island begins when new declarations are encountered. -- Michel Fortin michel.fortin michelf.com http://michelf.com/On 04/03/2012 10:27 AM, Don Clugston wrote:I don't see a way to just declare it as "illegal". How would you detect that situation in the general case? It's not easy. Y b() { ... } Y y = b(); X x = ... Prove that y doesn't depend on x.This is asking for a complicated special case. In global scope, order of declarations doesn't matter. In function scope, order of declarations always matters. If you have type inference of function returns, things can get nasty: void foo() { auto b() { return a(); } X x = whatever; auto a() { return x; } } Now b actually depends on the declaration of x. So it's not enough to say that only function declarations are immune to ordering rules.I come to a different conclusion. If only function declarations are immune to ordering rules, the above example is simply illegal. The example cannot be used to demonstrate incompleteness of the approach.
Apr 03 2012
On 04/03/2012 01:08 PM, Don Clugston wrote:Y b() { ... } Y y = b(); X x = ... Prove that y doesn't depend on x.Since only function declarations are immune to ordering rules, b cannot forward reference x.
Apr 03 2012
On 03/04/12 13:35, Timon Gehr wrote:On 04/03/2012 01:08 PM, Don Clugston wrote:But there could be another function a() which is below x, and which b() calls.Y b() { ... } Y y = b(); X x = ... Prove that y doesn't depend on x.Since only function declarations are immune to ordering rules, b cannot forward reference x.
Apr 03 2012
On 04/03/2012 01:55 PM, Don Clugston wrote:On 03/04/12 13:35, Timon Gehr wrote:This scenario can be forbidden conservatively.On 04/03/2012 01:08 PM, Don Clugston wrote:But there could be another function a() which is below x, and which b() calls.Y b() { ... } Y y = b(); X x = ... Prove that y doesn't depend on x.Since only function declarations are immune to ordering rules, b cannot forward reference x.
Apr 03 2012
On 03/04/12 13:58, Timon Gehr wrote:On 04/03/2012 01:55 PM, Don Clugston wrote:How?On 03/04/12 13:35, Timon Gehr wrote:This scenario can be forbidden conservatively.On 04/03/2012 01:08 PM, Don Clugston wrote:But there could be another function a() which is below x, and which b() calls.Y b() { ... } Y y = b(); X x = ... Prove that y doesn't depend on x.Since only function declarations are immune to ordering rules, b cannot forward reference x.
Apr 03 2012
On 04/03/2012 02:08 PM, Don Clugston wrote:On 03/04/12 13:58, Timon Gehr wrote:Don't allow forward referencing function a() if there is an intervening order-dependent declaration. (Alternatively, just analyse which symbols are referenced where and don't allow calling a local function that can transitively reach some symbols that have not yet been declared. I think this might be too complicated to be justifiable.)On 04/03/2012 01:55 PM, Don Clugston wrote:How?On 03/04/12 13:35, Timon Gehr wrote:This scenario can be forbidden conservatively.On 04/03/2012 01:08 PM, Don Clugston wrote:But there could be another function a() which is below x, and which b() calls.Y b() { ... } Y y = b(); X x = ... Prove that y doesn't depend on x.Since only function declarations are immune to ordering rules, b cannot forward reference x.
Apr 03 2012
"Don Clugston" <dac nospam.com> wrote in message news:jlelnn$tm4$1 digitalmars.com...I don't see a way to just declare it as "illegal". How would you detect that situation in the general case? It's not easy. Y b() { ... } Y y = b(); X x = ... Prove that y doesn't depend on x.We don't *have* to go the route of allowing nested functions to access forward-referenced variables. We could just limit it to forward-referenced nested functions. So this code could be illegal for exactly the same reason it's currently illegal: Y b() { /+ use the var 'x' +/ } Y y = b(); X x = ... If 'x' were a nested function instead of a variable, then *that* we could decide to start allowing: Y b() { /+ call function 'x' +/ } Y y = b(); X x() { ... } // b can access this because this is a nested func, not a var Of course, as you already pointed out and I replied to elsewhere in this thread, we'd still have to do something about this scenario: X b() { return a(); } X w = b(); X x = whatever; X a() { return x; } Alternatively, if I understand Timon right, I think he's suggesting that we could treat "groups" of nested function declarations as "unordered", and any one other statement/declaration would simply break the "group": // These three can all reference each other freely, // but they cannot reference f, x, y or z. A a() {...} B b() {...} C c() {...} // Something other than a nested function declaration. // This ends the "grouping" of a, b, and c. F f = ...; // These three can all reference each other freely. // Naturally, these can also reference a, b, c, and f X x() {...} Y y() {...} Z z() {...} That would allow mutual recursion while neatly avoiding any problems.
Apr 03 2012
On 03/04/12 13:51, Nick Sabalausky wrote:"Don Clugston"<dac nospam.com> wrote in message news:jlelnn$tm4$1 digitalmars.com...But it's the same. If you can forward reference a function, you can also access a variable. So this code could be illegal for exactly the same reasonI don't see a way to just declare it as "illegal". How would you detect that situation in the general case? It's not easy. Y b() { ... } Y y = b(); X x = ... Prove that y doesn't depend on x.We don't *have* to go the route of allowing nested functions to access forward-referenced variables. We could just limit it to forward-referenced nested functions.it's currently illegal:Y b() { /+ use the var 'x' +/ } Y y = b(); X x = ... If 'x' were a nested function instead of a variable, then *that* we could decide to start allowing: Y b() { /+ call function 'x' +/ } Y y = b(); X x() { ... } // b can access this because this is a nested func, not a var Of course, as you already pointed out and I replied to elsewhere in this thread, we'd still have to do something about this scenario: X b() { return a(); } X w = b(); X x = whatever; X a() { return x; }And I don't think there's any easy solution to that. I think it's a dead end.Alternatively, if I understand Timon right, I think he's suggesting that we could treat "groups" of nested function declarations as "unordered", and any one other statement/declaration would simply break the "group": // These three can all reference each other freely, // but they cannot reference f, x, y or z. A a() {...} B b() {...} C c() {...} // Something other than a nested function declaration. // This ends the "grouping" of a, b, and c. F f = ...; // These three can all reference each other freely. // Naturally, these can also reference a, b, c, and f X x() {...} Y y() {...} Z z() {...} That would allow mutual recursion while neatly avoiding any problems.Yeah, that'd work. It's a funky rule though.
Apr 03 2012
On 04/03/2012 07:38 AM, Nick Sabalausky wrote:Regarding this: http://d.puremagic.com/issues/show_bug.cgi?id=790 I submit that nested functions should be exempt from the usual sequential visibility rules. (Therefore, mutually recursive nested functions would become possible.) Or at the very *least*, this horrific C-like workaround should be possible: void foo() { void b(); void a() {...}; void b() {...}; } ...Flame away! ;)This is the right way to work around this issue. It works now and does not imply any kind of overhead at runtime: void foo(){ void a()(){ ... } void b() { ... } } However, I agree. Local functions that appear directly in sequence should be able to forward-reference each other. If some functions appearing in such a sequence have identical names, they should overload against each other.
Apr 03 2012
"Timon Gehr" <timon.gehr gmx.ch> wrote in message news:jlej27$mvi$1 digitalmars.com...This is the right way to work around this issue. It works now and does not imply any kind of overhead at runtime: void foo(){ void a()(){ ... } void b() { ... } }That's a very simple workaround (albiet unintuitive - unless I'm just too tired right now). It leads me to two questions: 1. How the heck does that work? 2. What, if any, problems would arise from just automatically doing that behind-the-scenes? Ie, to just automatically turn all non-templated nested functions into no-parameter templated nested functions? Would that be a feasable solution?
Apr 03 2012
On 04/03/2012 02:00 PM, Nick Sabalausky wrote:"Timon Gehr"<timon.gehr gmx.ch> wrote in message news:jlej27$mvi$1 digitalmars.com...Symbol lookup is done upon the first instantiation of the local template.This is the right way to work around this issue. It works now and does not imply any kind of overhead at runtime: void foo(){ void a()(){ ... } void b() { ... } }That's a very simple workaround (albiet unintuitive - unless I'm just too tired right now). It leads me to two questions: 1. How the heck does that work?2. What, if any, problems would arise from just automatically doing that behind-the-scenes? Ie, to just automatically turn all non-templated nested functions into no-parameter templated nested functions? Would that be a feasable solution?Your proposal is basically to allow a local function to forward reference any symbol that is declared before the local function is first referenced. This still has the following problem: void a(){/*cannot reference c*/} void b(){/*because this references a*/} void c(){/*references a and b*/ } It would work by reordering the code like so: void b(){/*references a*/} void a(){/*references c*/} void c(){/*references a and c*/} That would be extremely unintuitive.
Apr 03 2012
I'd argue it shouldn't work, but it'd require copying the scope. instantiation scope -> declaration scope -> sequence snapshot So again b shouldn't be is a's scope.Symbol lookup is done upon the first instantiation of the local template.void foo(){ void a()(){ ... } void b() { ... } }That's a very simple workaround (albiet unintuitive - unless I'm just too tired right now). It leads me to two questions: 1. How the heck does that work?
Apr 03 2012
On Tuesday, 3 April 2012 at 12:13:00 UTC, Timon Gehr wrote:On 04/03/2012 02:00 PM, Nick Sabalausky wrote:Currently, it prints 365. But remove the commented line, and it prints 500 twice. But it's a minor issue at worst that's easy to avoid, and this is a very simple workaround. int two() { return 500; } void main() { int x = 365; int one()() { return two(); } // writeln(one()); int two() { return x; } writeln(one()); } I found another solution involving templates, though not as convenient: template foo() { int one(){ return two(); } int two(){ return x + y; } int y = 12; } void main() { int x = 365; mixin foo; writeln(one()); }"Timon Gehr"<timon.gehr gmx.ch> wrote in message news:jlej27$mvi$1 digitalmars.com...Symbol lookup is done upon the first instantiation of the local template.This is the right way to work around this issue. It works now and does not imply any kind of overhead at runtime: void foo(){ void a()(){ ... } void b() { ... } }1. How the heck does that work?
Apr 04 2012
Nick Sabalausky:I submit that nested functions should be exempt from the usual sequential visibility rules. (Therefore, mutually recursive nested functions would become possible.)What about static nested functions? This seems a simpler enhancement request: import std.stdio; void main() { static int male(in int n) pure nothrow { return n ? (n - female(male(n - 1))) : 0; } static int female(in int n) pure nothrow { return n ? (n - male(female(n - 1))) : 1; } writeln(female(15)); } Bye, bearophile
Apr 03 2012
On 03/04/12 07:38, Nick Sabalausky wrote:Regarding this: http://d.puremagic.com/issues/show_bug.cgi?id=790 I submit that nested functions should be exempt from the usual sequential visibility rules. (Therefore, mutually recursive nested functions would become possible.) Or at the very *least*, this horrific C-like workaround should be possible: void foo() { void b(); void a() {...}; void b() {...}; } ...Flame away! ;)The most flexible method is to declare a local, nested struct. Any member functions (and variables!) of that struct have non-sequential semantics, so they can forward reference each other just fine. void foo() { struct Local { static void a() { b(); } static void b() { }; } Local.a(); } If they need to access stack variables, you'll need to create an actual instance of the struct. You can make it a static struct if they don't need access to any stack variables of foo. Note that this completely sidesteps all the nasty issues I mentioned in other posts.
Apr 04 2012
On 4/4/2012 12:57 AM, Don Clugston wrote:The most flexible method is to declare a local, nested struct. Any member functions (and variables!) of that struct have non-sequential semantics, so they can forward reference each other just fine.Thanks, Don. I didn't think of this, and it's an awesome solution. Can you put it in the D FAQ?
Apr 05 2012
It is a solution, but IMO it looks unpleasant. Reminds me C++, where I had to do this trick all the time.The most flexible method is to declare a local, nested struct.... it's an awesome solution.It's a morass of special cases.If D had a notion of pure pure functions - pure functions without any "concessions to practicality" then we could consider this simple rule: "local pure pure functions can be forward referenced".
Oct 10 2012