digitalmars.D - nested functions and closures
- Johannes Pfau (37/37) Feb 11 2013 When debugging gdc I've found some at least for me interesting
- Zach the Mystic (4/47) Feb 11 2013 I recently wrote an article partly on this topic which may be of
- Johannes Pfau (7/12) Feb 12 2013 Yes, that's basically the same question. I'm not really interested in
- Steven Schveighoffer (17/53) Feb 11 2013 A nested class has an outer pointer to it's owner class. You cannot
- Johannes Pfau (9/31) Feb 12 2013 Thanks, I thought it was something like that. The weird part is that if
- Steven Schveighoffer (15/46) Feb 12 2013 If structs inside functions acted just like structs outside of functions...
When debugging gdc I've found some at least for me interesting behavior which I'm trying to understand now: ---- auto testFunction() { int a = 41; int nestedFunc() { return ++a; } struct NestedStruct { int answer() { return nestedFunc(); } } return NestedStruct(); } writeln(testFunction().answer()); ---- This is valid D code, creates a closure. ---- class testClass { int a = 41; int nestedFunc() { return ++a; } struct NestedStruct { int answer() { return nestedFunc(); } } auto getStruct() { return NestedStruct(); } } writeln((new TestClass()).getStruct().answer); ---- This does not compile: test.d(33): Error: this for nestedFunc needs to be type testClass not type NestedStruct Is this intended? It seems to be very similar to the function closure code. Couldn't NestedStruct just get a pointer to the testClass to access its variables? Or am I missing something? Everything works fine if NestedStruct is a class and not a struct so I guess this functionality was disabled deliberately. But why? And why wasn't using a nested struct in functions in a similar way disallowed as well?
Feb 11 2013
On Monday, 11 February 2013 at 18:59:37 UTC, Johannes Pfau wrote:When debugging gdc I've found some at least for me interesting behavior which I'm trying to understand now: ---- auto testFunction() { int a = 41; int nestedFunc() { return ++a; } struct NestedStruct { int answer() { return nestedFunc(); } } return NestedStruct(); } writeln(testFunction().answer()); ---- This is valid D code, creates a closure. ---- class testClass { int a = 41; int nestedFunc() { return ++a; } struct NestedStruct { int answer() { return nestedFunc(); } } auto getStruct() { return NestedStruct(); } } writeln((new TestClass()).getStruct().answer); ---- This does not compile: test.d(33): Error: this for nestedFunc needs to be type testClass not type NestedStruct Is this intended? It seems to be very similar to the function closure code. Couldn't NestedStruct just get a pointer to the testClass to access its variables? Or am I missing something? Everything works fine if NestedStruct is a class and not a struct so I guess this functionality was disabled deliberately. But why? And why wasn't using a nested struct in functions in a similar way disallowed as well?I recently wrote an article partly on this topic which may be of interest to you. Apologies if it is not. See part one: neutrons. http://forum.dlang.org/thread/ririagrqecshjljcdubd forum.dlang.org
Feb 11 2013
Am Mon, 11 Feb 2013 21:41:26 +0100 schrieb "Zach the Mystic" <reachBUTMINUSTHISzach gOOGLYmail.com>:I recently wrote an article partly on this topic which may be of interest to you. Apologies if it is not. See part one: neutrons. http://forum.dlang.org/thread/ririagrqecshjljcdubd forum.dlang.orgYes, that's basically the same question. I'm not really interested in possible implementation details though, I'd just like to know why it wasn't allowed to access outer variables of nested structs in the first place. But Steven Schveighoffer answer already covers that.
Feb 12 2013
On Mon, 11 Feb 2013 13:59:36 -0500, Johannes Pfau <nospam example.com> wrote:When debugging gdc I've found some at least for me interesting behavior which I'm trying to understand now: ---- auto testFunction() { int a = 41; int nestedFunc() { return ++a; } struct NestedStruct { int answer() { return nestedFunc(); } } return NestedStruct(); } writeln(testFunction().answer()); ---- This is valid D code, creates a closure. ---- class testClass { int a = 41; int nestedFunc() { return ++a; } struct NestedStruct { int answer() { return nestedFunc(); } } auto getStruct() { return NestedStruct(); } } writeln((new TestClass()).getStruct().answer); ---- This does not compile: test.d(33): Error: this for nestedFunc needs to be type testClass not type NestedStruct Is this intended? It seems to be very similar to the function closure code. Couldn't NestedStruct just get a pointer to the testClass to access its variables? Or am I missing something? Everything works fine if NestedStruct is a class and not a struct so I guess this functionality was disabled deliberately. But why? And why wasn't using a nested struct in functions in a similar way disallowed as well?A nested class has an outer pointer to it's owner class. You cannot instantiate a nested class without it's owner class. A nested struct does NOT have a pointer to it's owner class. It's simply typed inside the class' namespace. FYI, nested classes were enshrined with a pointer to an outer instance for two reasons: 1. Their footprint is larger, not as big a hit to add another pointer. 2. To allow porting of Java code. Structs are POD for the most part, and are much more "bare metal" than classes. Nested structs could be given an instance pointer to the owner, but I think we would need a new construct for that. For your problem at hand, you may want to consider using interfaces instead. Or you can possibly embed the owner pointer manually. -Steve
Feb 11 2013
Am Mon, 11 Feb 2013 17:03:22 -0500 schrieb "Steven Schveighoffer" <schveiguy yahoo.com>:A nested class has an outer pointer to it's owner class. You cannot instantiate a nested class without it's owner class. A nested struct does NOT have a pointer to it's owner class. It's simply typed inside the class' namespace. FYI, nested classes were enshrined with a pointer to an outer instance for two reasons: 1. Their footprint is larger, not as big a hit to add another pointer. 2. To allow porting of Java code. Structs are POD for the most part, and are much more "bare metal" than classes. Nested structs could be given an instance pointer to the owner, but I think we would need a new construct for that.Thanks, I thought it was something like that. The weird part is that if you return a nested struct which is nested in a _function_ the compiler generates a closure for the function and then struct is given an instance pointer to the closure. But if you return a struct nested in a class the struct doesn't get an instance pointer.For your problem at hand, you may want to consider using interfaces instead. Or you can possibly embed the owner pointer manually. -SteveFortunately there's no problem at hand, I was just curious :-) I actually use nested classes/structs and closures quite rarely.
Feb 12 2013
On Tue, 12 Feb 2013 03:23:13 -0500, Johannes Pfau <nospam example.com> wrote:Am Mon, 11 Feb 2013 17:03:22 -0500 schrieb "Steven Schveighoffer" <schveiguy yahoo.com>:If structs inside functions acted just like structs outside of functions, there would be very little reason to have them. Functions sort of have their own namespace, but I don't know if that justifies having function-nested structs. There are static function-nested structs, but I think the concept of using them with frequency is pretty new (voldemort types). I actually wouldn't mind an opt-in approach to including an outer reference, at least for structs nested in classes (it's too dangerous to do this for owner structs). I think it's too late to make that the default.A nested class has an outer pointer to it's owner class. You cannot instantiate a nested class without it's owner class. A nested struct does NOT have a pointer to it's owner class. It's simply typed inside the class' namespace. FYI, nested classes were enshrined with a pointer to an outer instance for two reasons: 1. Their footprint is larger, not as big a hit to add another pointer. 2. To allow porting of Java code. Structs are POD for the most part, and are much more "bare metal" than classes. Nested structs could be given an instance pointer to the owner, but I think we would need a new construct for that.Thanks, I thought it was something like that. The weird part is that if you return a nested struct which is nested in a _function_ the compiler generates a closure for the function and then struct is given an instance pointer to the closure. But if you return a struct nested in a class the struct doesn't get an instance pointer.I use nested structs for namespace in dcollections quite frequently. For instance TreeMap.cursor is a nested struct. -SteveFor your problem at hand, you may want to consider using interfaces instead. Or you can possibly embed the owner pointer manually. -SteveFortunately there's no problem at hand, I was just curious :-) I actually use nested classes/structs and closures quite rarely.
Feb 12 2013