digitalmars.D - Calling nested function before declaration
- Jonathan (36/36) Sep 26 2018 This code fails to compile: ("undefined identifier fun")
- Neia Neutuladh (19/21) Sep 26 2018 void outerFunction()
- Timon Gehr (9/17) Sep 27 2018 * turn the function with the forward reference into a template
- Timon Gehr (8/12) Sep 27 2018 The current behavior is easy to specify and simple to implement, and it
- Walter Bright (7/13) Sep 27 2018 Right. Functions tend to be short, and it's very rare that a function ca...
- nkm1 (13/49) Sep 27 2018 One of the reasons is consistency perhaps. Functions are not
This code fails to compile: ("undefined identifier fun") void main() { fun(); void fun() {} } Having the call after the declaration works: void main() { void fun() {} fun(); } Is this how it is intended to work? It seems goofy that this works: void main() { void fun2() {} void fun() { fun2() } fun(); } But this fails to compile: ("undefined identifier fun2") void main() { void fun() { fun2() } void fun2() {} fun(); } What if I wanted this? void main() { void fun2() {fun();} void fun() {fun2();} fun(); } I can't see how the current behavior is at all better or to be preferred unless it is faster to compile? What is the reason for it being how it is?
Sep 26 2018
On 09/26/2018 03:46 PM, Jonathan wrote:I can't see how the current behavior is at all better or to be preferred unless it is faster to compile? What is the reason for it being how it is?void outerFunction() { func(); auto lock = acquireLock(); void nested() { } } Inside `nested`, can you refer to `lock`? It's in lexical scope, so yes. It hasn't been initialized yet. What value should it have? Presumably its standard uninitialized value. This is likely to cause a lot of confusion. The standard ways of dealing with this: * Reorder the declarations. * Make the functions non-nested. * Get rid of mutual recursion. * Use a delegate. * Do a method-to-method-object refactoring.
Sep 26 2018
On 27.09.2018 01:05, Neia Neutuladh wrote:The standard ways of dealing with this: * Reorder the declarations. * Make the functions non-nested. * Get rid of mutual recursion. * Use a delegate. * Do a method-to-method-object refactoring.* turn the function with the forward reference into a template void main() { void fun()() { fun2(); } void fun2() {} fun(); // ok }
Sep 27 2018
On 27.09.2018 00:46, Jonathan wrote:I can't see how the current behavior is at all better or to be preferred unless it is faster to compile? What is the reason for it being how it is?The current behavior is easy to specify and simple to implement, and it is what Walter has implemented. A better behavior that is almost as simple to implement would be to insert nested functions into the symbol table in blocks of back-to-back-defined nested functions, but that would be a breaking language change at this point. (Maybe you can get a DIP though though.) Otherwise, the template workaround is a bit ugly but it works and is non-intrusive.
Sep 27 2018
On 9/27/2018 11:33 AM, Timon Gehr wrote:The current behavior is easy to specify and simple to implement, and it is what Walter has implemented. A better behavior that is almost as simple to implement would be to insert nested functions into the symbol table in blocks of back-to-back-defined nested functions, but that would be a breaking language change at this point. (Maybe you can get a DIP though though.) Otherwise, the template workaround is a bit ugly but it works and is non-intrusive.Right. Functions tend to be short, and it's very rare that a function cannot be defined before use. One such case is mutually recursive functions. But as Timon showed, there is a simple workaround for this, and has been suggested, a delegate can be used, too. And as Timon also suggested, the straightforwardness of the existing approach is an advantage and is intended.
Sep 27 2018
On Wednesday, 26 September 2018 at 22:46:21 UTC, Jonathan wrote:This code fails to compile: ("undefined identifier fun") void main() { fun(); void fun() {} } Having the call after the declaration works: void main() { void fun() {} fun(); } Is this how it is intended to work? It seems goofy that this works: void main() { void fun2() {} void fun() { fun2() } fun(); } But this fails to compile: ("undefined identifier fun2") void main() { void fun() { fun2() } void fun2() {} fun(); } What if I wanted this? void main() { void fun2() {fun();} void fun() {fun2();} fun(); } I can't see how the current behavior is at all better or to be preferred unless it is faster to compile? What is the reason for it being how it is?One of the reasons is consistency perhaps. Functions are not different from other identifiers: void fun1() { writeln(x); } int x = 1; void fun2() { writeln(y); // fails ("undefined indentifier y") int y = 2; }
Sep 27 2018