digitalmars.D - reference to 'self' inside a function
- angel (8/8) Jul 17 2012 I propose to introduce a reference to the current function, much
- Kevin Cox (5/9) Jul 17 2012 reasonable names for these functions becomes unnecessarily painful.
- H. S. Teoh (11/24) Jul 17 2012 We certainly can't use 'this', because it will break lambda functions
- Timon Gehr (6/12) Jul 17 2012 I think it is not the naming that is painful. (I am not aware of
- angel (5/5) Jul 17 2012 Other languages provide other means.
- bearophile (4/7) Jul 17 2012 Or __func or something. I'm asking for it for years.
- Jonathan M Davis (4/10) Jul 17 2012 You could always use __FUNCTION__ in a string mixin, but that _is_ rathe...
- Jonathan M Davis (4/10) Jul 17 2012 You could always use __FUNCTION__ in a string mixin, but that _is_ rathe...
- angel (14/16) Jul 18 2012 Like this ?
- Eyyub (4/12) Jul 17 2012 Good idea !
- Era Scarecrow (23/35) Jul 17 2012 Mmm.. Why not an inner function to represent the recursive
- Kevin Cox (13/25) Jul 17 2012 style, one creates many functions, and looking for reasonable names for
- FeepingCreature (3/31) Jul 18 2012 Sadly, this collides with the return-type syntax already in place.
- Mehrdad (7/15) Jul 18 2012 Recursive lambdas? o.O
- Timon Gehr (9/22) Jul 19 2012 - D does/can not have full type inference, because the type system with
- Nathan M. Swan (6/14) Jul 19 2012 May I suggest the "recur" or "recursive" keyword?
- Rob T (36/36) Sep 18 2012 I was just about to make this proposal myself before searching to
- Ben Davis (8/40) Sep 18 2012 Wild stab in the dark, but would something like this work:
- Ben Davis (4/56) Sep 18 2012 Or indeed
- Rob T (16/23) Sep 18 2012 This hack will generate the enclosing function name
- Ben Davis (9/34) Sep 18 2012 I agree - except I wouldn't reserve 'self' as a keyword. I'd probably
- Rob T (26/35) Sep 18 2012 Actually I find the __traits system a bit convoluted and
- Jacob Carlborg (11/33) Sep 19 2012 I think the reason for this is that the compiler will resolve "main" as
- Jacob Carlborg (6/8) Sep 19 2012 I would not call the reflection abilities in D good. D has reflection
- Nick Treleaven (12/32) Sep 22 2012 I've just made a wrapper that helps - you have to use mixin with it:
- Rob T (15/26) Sep 23 2012 Thanks, for comming up with this clever solution, it's the best
- Ben Davis (9/37) Sep 23 2012 Here's another one that might work, and be less error-prone:
- Philippe Sigaud (4/12) Sep 23 2012 Oh, you're using {} as a local block (or anonymous delegate), right?
- Ben Davis (4/19) Sep 23 2012 Actually I stole the {} from Nick's suggestion. My suggestion was using
- Philippe Sigaud (4/7) Sep 23 2012 Ah, OK :) I actually just skimmed the entire thread :) I think self
- Rob T (20/28) Sep 24 2012 OK, we've managed to get the calling function symbol name without
- Rob T (14/45) Sep 24 2012 This is a little insane, but it works.
- Nick Treleaven (9/21) Sep 25 2012 enum string self = q{__traits(parent, {})};
I propose to introduce a reference to the current function, much like 'this' in a class method. Call it 'self' or 'thisFunc', or whatever ... What might this be good for ? For implementing recursion in a lambda function. Writing in functional style, one creates many functions, and looking for reasonable names for these functions becomes unnecessarily painful.
Jul 17 2012
On Jul 17, 2012 1:00 PM, "angel" <andrey.gelman gmail.com> wrote:I propose to introduce a reference to the current function, much like'this' in a class method. Call it 'self' or 'thisFunc', or whatever ...What might this be good for ? For implementing recursion in a lambda function. Writing in functional style, one creates many functions, and looking forreasonable names for these functions becomes unnecessarily painful. I like that idea, although I don't know about the name. We also might want more features such as access to syntacticly nested functions.
Jul 17 2012
On Tue, Jul 17, 2012 at 01:09:09PM -0400, Kevin Cox wrote:On Jul 17, 2012 1:00 PM, "angel" <andrey.gelman gmail.com> wrote:We certainly can't use 'this', because it will break lambda functions declared inside class methods. So 'self' seems like a reasonable alternative. But this requires introducing a new keyword, which means there's the likelihood of breaking existing code that happens to use an identifier called 'self'. It's a good idea, though. It will strengthen D's support for functional style code. T -- Let's eat some disquits while we format the biskettes.I propose to introduce a reference to the current function, much like 'this' in a class method. Call it 'self' or 'thisFunc', or whatever ... What might this be good for ? For implementing recursion in a lambda function. Writing in functional style, one creates many functions, and looking for reasonable names for these functions becomes unnecessarily painful.I like that idea, although I don't know about the name. We also might want more features such as access to syntacticly nested functions.
Jul 17 2012
On 07/17/2012 06:56 PM, angel wrote:I propose to introduce a reference to the current function, much like 'this' in a class method. Call it 'self' or 'thisFunc', or whatever ... What might this be good for ? For implementing recursion in a lambda function. Writing in functional style, one creates many functions, and looking for reasonable names for these functions becomes unnecessarily painful.I think it is not the naming that is painful. (I am not aware of functional languages that have a special identifier for the current anonymous function.) What makes writing short named functions inconvenient is lack of this: http://d.puremagic.com/issues/show_bug.cgi?id=7176
Jul 17 2012
Other languages provide other means. In any case, I don't think it would be a problem if D solved a problem other languages failed to resolve properly. As for http://d.puremagic.com/issues/show_bug.cgi?id=7176, this is pretty much orthogonal to the 'self reference'.
Jul 17 2012
angel:I propose to introduce a reference to the current function, much like 'this' in a class method. Call it 'self' or 'thisFunc', or whatever ...Or __func or something. I'm asking for it for years. Bye, bearophile
Jul 17 2012
On Wednesday, July 18, 2012 00:03:25 bearophile wrote:angel:You could always use __FUNCTION__ in a string mixin, but that _is_ rather ugly. - Jonathan M DavisI propose to introduce a reference to the current function, much like 'this' in a class method. Call it 'self' or 'thisFunc', or whatever ...Or __func or something. I'm asking for it for years.
Jul 17 2012
On Wednesday, July 18, 2012 00:03:25 bearophile wrote:angel:You could always use __FUNCTION__ in a string mixin, but that _is_ rather ugly. - Jonathan M DavisI propose to introduce a reference to the current function, much like 'this' in a class method. Call it 'self' or 'thisFunc', or whatever ...Or __func or something. I'm asking for it for years.
Jul 17 2012
You could always use __FUNCTION__ in a string mixin, but that _is_ rather ugly.Like this ? auto fac = delegate(int n) { if (n <= 1) return 1; return n * mixin(__FUNCTION__)(n - 1); }; Well, there are a few problems with this: - it _is_ ugly - some 'automatic' name should be generated internally (possibly it is in any case) - it doesn't currently work Possibly more streamlined approach would be: thisFunc (or 'self', or whatever) thisFunc.stringof istead of __FUNCTION__
Jul 18 2012
On Tuesday, 17 July 2012 at 16:56:17 UTC, angel wrote:I propose to introduce a reference to the current function, much like 'this' in a class method. Call it 'self' or 'thisFunc', or whatever ... What might this be good for ? For implementing recursion in a lambda function. Writing in functional style, one creates many functions, and looking for reasonable names for these functions becomes unnecessarily painful.Good idea ! "self" is a cute keyword, or "lambda" but this could break existing code.
Jul 17 2012
On Tuesday, 17 July 2012 at 22:13:13 UTC, Eyyub wrote:On Tuesday, 17 July 2012 at 16:56:17 UTC, angel wrote:Mmm.. Why not an inner function to represent the recursive function? True a 'self' reference may resolve the issue, and be syntactical sugar.. auto f = function int(int x) { //real function body void self(int y) { if(y) { inner(y-1); x++; } } self(x); //double x self(x); //double it again return x; }; //end of f declaration writeln(10); writeln(f(10)); //10*4 Mmm But using it as a shell although may work wouldn't be useful for a simple lambda anymore would it? Who knows, perhaps 'this' will extend to lambda's referencing itself. Using CTFE you could rebuild and get something similar to that, or a template function... Hmmmm... Something to think on...I propose to introduce a reference to the current function, much like 'this' in a class method. Call it 'self' or 'thisFunc', or whatever ... What might this be good for ? For implementing recursion in a lambda function. Writing in functional style, one creates many functions, and looking for reasonable names for these functions becomes unnecessarily painful.Good idea ! "self" is a cute keyword, or "lambda" but this could break existing code.
Jul 17 2012
On Jul 17, 2012 6:50 PM, "Era Scarecrow" <rtcvb32 yahoo.com> wrote:On Tuesday, 17 July 2012 at 22:13:13 UTC, Eyyub wrote:'this' in a class method. Call it 'self' or 'thisFunc', or whatever ...On Tuesday, 17 July 2012 at 16:56:17 UTC, angel wrote:I propose to introduce a reference to the current function, much likestyle, one creates many functions, and looking for reasonable names for these functions becomes unnecessarily painful.What might this be good for ? For implementing recursion in a lambda function. Writing in functionala 'self' reference may resolve the issue, What about how JavaScript does it. Anonymous functions can still have a "name" that can be used from inside of a function to refer to itself. And the most useless example ever. var f = function func ( i ) { return func(7); }; I think that this is nice because there is no name space pollution, no new keywords needed and it is pretty.Good idea ! "self" is a cute keyword, or "lambda" but this could break existing code.Mmm.. Why not an inner function to represent the recursive function? True
Jul 17 2012
On 07/18/12 01:05, Kevin Cox wrote:On Jul 17, 2012 6:50 PM, "Era Scarecrow" <rtcvb32 yahoo.com <mailto:rtcvb32 yahoo.com>> wrote:Sadly, this collides with the return-type syntax already in place. auto f = function int(int i) { return 0; };On Tuesday, 17 July 2012 at 22:13:13 UTC, Eyyub wrote:What about how JavaScript does it. Anonymous functions can still have a "name" that can be used from inside of a function to refer to itself. And the most useless example ever. var f = function func ( i ) { return func(7); }; I think that this is nice because there is no name space pollution, no new keywords needed and it is pretty.On Tuesday, 17 July 2012 at 16:56:17 UTC, angel wrote:Mmm.. Why not an inner function to represent the recursive function? True a 'self' reference may resolve the issue,I propose to introduce a reference to the current function, much like 'this' in a class method. Call it 'self' or 'thisFunc', or whatever ... What might this be good for ? For implementing recursion in a lambda function. Writing in functional style, one creates many functions, and looking for reasonable names for these functions becomes unnecessarily painful.Good idea ! "self" is a cute keyword, or "lambda" but this could break existing code.
Jul 18 2012
On Jul 18, 2012 6:20 AM, "FeepingCreature" <default_357-line yahoo.de> wrote:On 07/18/12 01:05, Kevin Cox wrote:a "name" that can be used from inside of a function to refer to itself.What about how JavaScript does it. Anonymous functions can still haveSadly, this collides with the return-type syntax already in place. auto f = function int(int i) { return 0; };True, but the concept could still be used, we just need some syntax.
Jul 18 2012
True, but the concept could still be used, we just need some syntax.IMHO introducing a new keyword is the clearest solution. As for the danger of breaking existing code, let's face it, there is no whole world legacy written in D with extensive use of 'thisFunc' keyword.
Jul 18 2012
On Tuesday, 17 July 2012 at 16:56:17 UTC, angel wrote:I propose to introduce a reference to the current function, much like 'this' in a class method. Call it 'self' or 'thisFunc', or whatever ... What might this be good for ? For implementing recursion in a lambda function. Writing in functional style, one creates many functions, and looking for reasonable names for these functions becomes unnecessarily painful.Recursive lambdas? o.O Instead of changing the language, I'd say your situation merits using the Y combinator... maybe define Y(f) to be (g => g(g))(g => f(x => g(g)(x))) then if you need to define factorial, just say... fact = Y(fact => n => n > 0 ? n * fact(n - 1) : 1);
Jul 18 2012
On 07/19/2012 04:54 AM, Mehrdad wrote:On Tuesday, 17 July 2012 at 16:56:17 UTC, angel wrote:- D does/can not have full type inference, because the type system with templates is Turing complete. - There is no way this is going to type check even with explicit type annotations, because there are no recursive function types. - Allocation of closures for control flow is not going to work efficiently with the current GC. - D actually has named functions, there is no need to use the anonymous lambda based y combinator to make up for the lack of them.I propose to introduce a reference to the current function, much like 'this' in a class method. Call it 'self' or 'thisFunc', or whatever ... What might this be good for ? For implementing recursion in a lambda function. Writing in functional style, one creates many functions, and looking for reasonable names for these functions becomes unnecessarily painful.Recursive lambdas? o.O Instead of changing the language, I'd say your situation merits using the Y combinator... maybe define Y(f) to be (g => g(g))(g => f(x => g(g)(x))) then if you need to define factorial, just say... fact = Y(fact => n => n > 0 ? n * fact(n - 1) : 1);
Jul 19 2012
On Tuesday, 17 July 2012 at 16:56:17 UTC, angel wrote:I propose to introduce a reference to the current function, much like 'this' in a class method. Call it 'self' or 'thisFunc', or whatever ... What might this be good for ? For implementing recursion in a lambda function. Writing in functional style, one creates many functions, and looking for reasonable names for these functions becomes unnecessarily painful.May I suggest the "recur" or "recursive" keyword? auto factorials = map!(n => n ? n * recur(n-1) : 1)([1, 2, 3]).array; assert(factorials == [1, 2, 6]); NMS
Jul 19 2012
I was just about to make this proposal myself before searching to see if it had already been discussed, so here I am. The requirement for self-referencing is a lot more profound than providing only a means to self-reference a calling function (runtime or during compile time). I recently decided to drop C++ and commit to using D for a production system (yeah I'm taking a risk), and almost immediately the first problem I encounter is this insanely frustrating inability: For logging errors in my code, I want to log the calling function name along with other applicable information. I can do a lot with D, but I cannot get access to the calling function name in a reasonable way (all solutions I have found so far are IMO unreasonable). I can easily log class names from a member function, eg typeof(this).stringof So why can't I do a similar thing with member functions? or any other type that has internal member code? or more profoundly, any type in general eg entity.this? (I know 'this' is a special key word, I re-use it to illustrate the point) I recall how it was nice to hear that D did away with the need to prefix class names onto cstors and dstors (that was required for more than one reason), so here is the opportunity to do the same thing with functions, such that recursive calling does not require explicityly re-naming the same function over again. I also realize that there's a need to introduce better compile time reflection and runtime reflection, so here is an opportunity to unify a few things that directly apply to both of these efforts. Self-referencing should be generalized and applicable to all entities, not just classes and structs. It could make templates easier to write, it directly applies to improved compile and runtime reflection, and it elegantly solves real world proplems, such as my simple error logger requirement. --rt
Sep 18 2012
Wild stab in the dark, but would something like this work: void myfunction() { int dummy; auto self = __traits(parent, dummy); } though it would be better if something like __traits(enclosing) were supported. On 18/09/2012 20:22, Rob T wrote:I was just about to make this proposal myself before searching to see if it had already been discussed, so here I am. The requirement for self-referencing is a lot more profound than providing only a means to self-reference a calling function (runtime or during compile time). I recently decided to drop C++ and commit to using D for a production system (yeah I'm taking a risk), and almost immediately the first problem I encounter is this insanely frustrating inability: For logging errors in my code, I want to log the calling function name along with other applicable information. I can do a lot with D, but I cannot get access to the calling function name in a reasonable way (all solutions I have found so far are IMO unreasonable). I can easily log class names from a member function, eg typeof(this).stringof So why can't I do a similar thing with member functions? or any other type that has internal member code? or more profoundly, any type in general eg entity.this? (I know 'this' is a special key word, I re-use it to illustrate the point) I recall how it was nice to hear that D did away with the need to prefix class names onto cstors and dstors (that was required for more than one reason), so here is the opportunity to do the same thing with functions, such that recursive calling does not require explicityly re-naming the same function over again. I also realize that there's a need to introduce better compile time reflection and runtime reflection, so here is an opportunity to unify a few things that directly apply to both of these efforts. Self-referencing should be generalized and applicable to all entities, not just classes and structs. It could make templates easier to write, it directly applies to improved compile and runtime reflection, and it elegantly solves real world proplems, such as my simple error logger requirement. --rt
Sep 18 2012
Or indeed auto self = __traits(parent, self); Grin :) On 18/09/2012 20:57, Ben Davis wrote:Wild stab in the dark, but would something like this work: void myfunction() { int dummy; auto self = __traits(parent, dummy); } though it would be better if something like __traits(enclosing) were supported. On 18/09/2012 20:22, Rob T wrote:I was just about to make this proposal myself before searching to see if it had already been discussed, so here I am. The requirement for self-referencing is a lot more profound than providing only a means to self-reference a calling function (runtime or during compile time). I recently decided to drop C++ and commit to using D for a production system (yeah I'm taking a risk), and almost immediately the first problem I encounter is this insanely frustrating inability: For logging errors in my code, I want to log the calling function name along with other applicable information. I can do a lot with D, but I cannot get access to the calling function name in a reasonable way (all solutions I have found so far are IMO unreasonable). I can easily log class names from a member function, eg typeof(this).stringof So why can't I do a similar thing with member functions? or any other type that has internal member code? or more profoundly, any type in general eg entity.this? (I know 'this' is a special key word, I re-use it to illustrate the point) I recall how it was nice to hear that D did away with the need to prefix class names onto cstors and dstors (that was required for more than one reason), so here is the opportunity to do the same thing with functions, such that recursive calling does not require explicityly re-naming the same function over again. I also realize that there's a need to introduce better compile time reflection and runtime reflection, so here is an opportunity to unify a few things that directly apply to both of these efforts. Self-referencing should be generalized and applicable to all entities, not just classes and structs. It could make templates easier to write, it directly applies to improved compile and runtime reflection, and it elegantly solves real world proplems, such as my simple error logger requirement. --rt
Sep 18 2012
On Tuesday, 18 September 2012 at 19:57:05 UTC, Ben Davis wrote:Wild stab in the dark, but would something like this work: void myfunction() { int dummy; auto self = __traits(parent, dummy); } though it would be better if something like __traits(enclosing) were supported.This hack will generate the enclosing function name void function x() { int dummy; auto funcname = __traits( identifier, __traits( parent, dummy ) ); writefln( funcname ); } Obviously the above solution is not reasonable, esp for a language that attempts to provide good reflection abilities. What would work considerably better is something ike this void function x() { writeln(self.symbolname); }
Sep 18 2012
On 18/09/2012 22:21, Rob T wrote:On Tuesday, 18 September 2012 at 19:57:05 UTC, Ben Davis wrote:I agree - except I wouldn't reserve 'self' as a keyword. I'd probably extend the existing __traits mechanism, avoiding the need for the dummy/parent hack. Possibly also create a shortcut for nested __traits? It's not down to me though - I just wanted to give you something to work with so you can get your project working. D has a bug tracker where you could post the feature request: http://d.puremagic.com/issues/enter_bug.cgi?product=D Good luck :)Wild stab in the dark, but would something like this work: void myfunction() { int dummy; auto self = __traits(parent, dummy); } though it would be better if something like __traits(enclosing) were supported.This hack will generate the enclosing function name void function x() { int dummy; auto funcname = __traits( identifier, __traits( parent, dummy ) ); writefln( funcname ); } Obviously the above solution is not reasonable, esp for a language that attempts to provide good reflection abilities. What would work considerably better is something ike this void function x() { writeln(self.symbolname); }
Sep 18 2012
Actually I find the __traits system a bit convoluted and inconsistent with other similar features. There seems to be a real need to unify the different methods of reflection in D. For example, I can do this without using __traits int i; writeln( i.stringof ); and I can do this void function x() {}; writeln( x.stringof ); but it won't work for the main function int main(char[][] args) { writeln( main.stringof ); // compile error (bug?) } but this works writeln(__traits( identifier, main )); It seems that __traits(itentifier, ) and .stringof are two ways of getting access to the same information. So why do we have __traits and the built in properties that overlap in functionality? Why is it inconsistently applied as seen with function main (although that could simply be a bug)? The situation is rather confusing. I'll try the bug tracker to report the need for a "self" solution, and the inconsistent application of .stringof where it fails with main function. I sure hope the situation will improve.I agree - except I wouldn't reserve 'self' as a keyword. I'd probably extend the existing __traits mechanism, avoiding the need for the dummy/parent hack. Possibly also create a shortcut for nested __traits? It's not down to me though - I just wanted to give you something to work with so you can get your project working. D has a bug tracker where you could post the feature request: http://d.puremagic.com/issues/enter_bug.cgi?product=D Good luck :)
Sep 18 2012
On 2012-09-19 01:21, Rob T wrote:Actually I find the __traits system a bit convoluted and inconsistent with other similar features. There seems to be a real need to unify the different methods of reflection in D. For example, I can do this without using __traits int i; writeln( i.stringof ); and I can do this void function x() {}; writeln( x.stringof ); but it won't work for the main function int main(char[][] args) { writeln( main.stringof ); // compile error (bug?) }I think the reason for this is that the compiler will resolve "main" as a function call, but it will fail because no arguments are given. This is a typical feature where it seems no one really know how it should behave. .stringof is very poorly documented. It says nothing about what the returned string might look like.but this works writeln(__traits( identifier, main )); It seems that __traits(itentifier, ) and .stringof are two ways of getting access to the same information. So why do we have __traits and the built in properties that overlap in functionality? Why is it inconsistently applied as seen with function main (although that could simply be a bug)? The situation is rather confusing..stringof was available long before D2 was created, __traits is only available in D2. I think __traits was create to try to improve the compile time reflection abilities in D. -- /Jacob Carlborg
Sep 19 2012
I found this discussion, Time for std.reflection http://forum.dlang.org/thread/juf7sk$16rl$1 digitalmars.com so maybe if the effort gets underway (or perhaps it is already) then we'll see significant improvemnts with D's reflection. --rt
Sep 19 2012
On 19/09/2012 08:24, Jacob Carlborg wrote:On 2012-09-19 01:21, Rob T wrote:I don't think that's true, is it? It would be true if main was marked property, but it isn't, so it's only a call if you have () after it. I'd expect "main" to resolve to either a function or (if overloaded) a function set, and then - if it's not a set - you could pass it around like a C function pointer. (If it is a set, I have no idea.)Actually I find the __traits system a bit convoluted and inconsistent with other similar features. There seems to be a real need to unify the different methods of reflection in D. For example, I can do this without using __traits int i; writeln( i.stringof ); and I can do this void function x() {}; writeln( x.stringof ); but it won't work for the main function int main(char[][] args) { writeln( main.stringof ); // compile error (bug?) }I think the reason for this is that the compiler will resolve "main" as a function call, but it will fail because no arguments are given. This is a typical feature where it seems no one really know how it should behave. .stringof is very poorly documented. It says nothing about what the returned string might look like.Hmm, it does seem that way, doesn't it?but this works writeln(__traits( identifier, main )); It seems that __traits(itentifier, ) and .stringof are two ways of getting access to the same information.If it helps, I recently discovered the std.traits library, which wraps a lot of those ugly low-level-looking things in cleaner-looking things. I couldn't see the 'self' use case in there though.So why do we have __traits and the built in properties that overlap in functionality? Why is it inconsistently applied as seen with function main (although that could simply be a bug)? The situation is rather confusing..stringof was available long before D2 was created, __traits is only available in D2. I think __traits was create to try to improve the compile time reflection abilities in D.
Sep 22 2012
On 2012-09-18 23:21, Rob T wrote:Obviously the above solution is not reasonable, esp for a language that attempts to provide good reflection abilities.I would not call the reflection abilities in D good. D has reflection abilities but they are far from good. Most are different hacks bolt together. -- /Jacob Carlborg
Sep 19 2012
On 18/09/2012 22:21, Rob T wrote:On Tuesday, 18 September 2012 at 19:57:05 UTC, Ben Davis wrote:I've just made a wrapper that helps - you have to use mixin with it: string scopeName() { return q{__traits(identifier, __traits(parent, {}))}; } void main() { writeln(mixin(scopeName())); } That should be quite usable, except if the user forgets the mixin() part - unfortunately that potential bug seems to be statically undetectable.Wild stab in the dark, but would something like this work: void myfunction() { int dummy; auto self = __traits(parent, dummy); } though it would be better if something like __traits(enclosing) were supported.This hack will generate the enclosing function name void function x() { int dummy; auto funcname = __traits( identifier, __traits( parent, dummy ) ); writefln( funcname ); } Obviously the above solution is not reasonable, esp for a language that attempts to provide good reflection abilities.
Sep 22 2012
string scopeName() { return q{__traits(identifier, __traits(parent, {}))}; } void main() { writeln(mixin(scopeName())); } That should be quite usable, except if the user forgets the mixin() part - unfortunately that potential bug seems to be statically undetectable.Thanks, for comming up with this clever solution, it's the best one so far, and I will likely be using it. The real problem of course is that there is no simple or obvious solution to what is a very basic requirment - to inspect information about a calling function, and/or execute it recursively without having to re-specify the function explicitly. Don't get me wrong, I am very much impressed with D, but the reflection component in D should be made a real part of the language, and really ought to be made more generalized (elegant). It is interesting that both classes and structs are able to refer to themselves through "this", so that's a hint that there may be some more use to the idea of self-referencing elsewhere. For example, the ctors and dtors refer back to "this", hinting that functions should be able to do the same thing for recursive calls. --rt
Sep 23 2012
Here's another one that might work, and be less error-prone: mixin template Self() { auto self = __traits(identifier, __traits(parent, {})); } void test() { mixin Self; writeln(self); } On 23/09/2012 09:58, Rob T wrote:string scopeName() { return q{__traits(identifier, __traits(parent, {}))}; } void main() { writeln(mixin(scopeName())); } That should be quite usable, except if the user forgets the mixin() part - unfortunately that potential bug seems to be statically undetectable.Thanks, for comming up with this clever solution, it's the best one so far, and I will likely be using it. The real problem of course is that there is no simple or obvious solution to what is a very basic requirment - to inspect information about a calling function, and/or execute it recursively without having to re-specify the function explicitly. Don't get me wrong, I am very much impressed with D, but the reflection component in D should be made a real part of the language, and really ought to be made more generalized (elegant). It is interesting that both classes and structs are able to refer to themselves through "this", so that's a hint that there may be some more use to the idea of self-referencing elsewhere. For example, the ctors and dtors refer back to "this", hinting that functions should be able to do the same thing for recursive calls. --rt
Sep 23 2012
On Sun, Sep 23, 2012 at 7:16 PM, Ben Davis <entheh cantab.net> wrote:Here's another one that might work, and be less error-prone: mixin template Self() { auto self = __traits(identifier, __traits(parent, {})); } void test() { mixin Self; writeln(self); }Oh, you're using {} as a local block (or anonymous delegate), right? That's a nice trick. I even works at the module level, nice one!
Sep 23 2012
On 23/09/2012 20:58, Philippe Sigaud wrote:On Sun, Sep 23, 2012 at 7:16 PM, Ben Davis <entheh cantab.net> wrote:Actually I stole the {} from Nick's suggestion. My suggestion was using a mixin template instead of a string mixin, making it harder to screw up invoking the mixin :)Here's another one that might work, and be less error-prone: mixin template Self() { auto self = __traits(identifier, __traits(parent, {})); } void test() { mixin Self; writeln(self); }Oh, you're using {} as a local block (or anonymous delegate), right? That's a nice trick. I even works at the module level, nice one!
Sep 23 2012
On Sun, Sep 23, 2012 at 11:45 PM, Ben Davis <entheh cantab.net> wrote:Actually I stole the {} from Nick's suggestion. My suggestion was using a mixin template instead of a string mixin, making it harder to screw up invoking the mixin :)Ah, OK :) I actually just skimmed the entire thread :) I think self should be in Phobos, that's something I had to re-implement many times. And I never thought of using {}.
Sep 23 2012
On Sunday, 23 September 2012 at 17:15:13 UTC, Ben Davis wrote:Here's another one that might work, and be less error-prone: mixin template Self() { auto self = __traits(identifier, __traits(parent, {})); } void test() { mixin Self; writeln(self); }OK, we've managed to get the calling function symbol name without re-specifying it. Now I wonder if we can perform mixin magic to execute a function recursively without re-specifying the function name? Example recursive function int Recurse(int a) { if (a <= 1) return 1; else // can we replace explicit call to "Recurse" // with "self" using a mixin or some other means? return a * Recurse(a - 1); } We could try and get the function pointer, but that seems like the wrong approach. I'd rather get the function name, do some mixin magic with it to generate the compile time code that uses the function name directly. Can we mixin a mixin??? --rt
Sep 24 2012
This is a little insane, but it works. int Recurse(int a) { if (a <= 1) return 1; else // can we replace explicit call to "Recurse" // with "self" using a mixin or some other means? // return a * Recurse(a - 1); mixin("return a * mixin(__traits(identifier, __traits(parent, {})))(a - 1);"); } --rt On Tuesday, 25 September 2012 at 04:42:43 UTC, Rob T wrote:On Sunday, 23 September 2012 at 17:15:13 UTC, Ben Davis wrote:Here's another one that might work, and be less error-prone: mixin template Self() { auto self = __traits(identifier, __traits(parent, {})); } void test() { mixin Self; writeln(self); }OK, we've managed to get the calling function symbol name without re-specifying it. Now I wonder if we can perform mixin magic to execute a function recursively without re-specifying the function name? Example recursive function int Recurse(int a) { if (a <= 1) return 1; else // can we replace explicit call to "Recurse" // with "self" using a mixin or some other means? return a * Recurse(a - 1); } We could try and get the function pointer, but that seems like the wrong approach. I'd rather get the function name, do some mixin magic with it to generate the compile time code that uses the function name directly. Can we mixin a mixin??? --rt
Sep 24 2012
On 25/09/2012 06:07, Rob T wrote:This is a little insane, but it works. int Recurse(int a) { if (a <= 1) return 1; else // can we replace explicit call to "Recurse" // with "self" using a mixin or some other means? // return a * Recurse(a - 1); mixin("return a * mixin(__traits(identifier, __traits(parent, {})))(a - 1);"); }enum string self = q{__traits(parent, {})}; int recurse(int a) { if (a <= 1) return 1; else return a * mixin(self)(a - 1); }
Sep 25 2012