www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - reference to 'self' inside a function

reply "angel" <andrey.gelman gmail.com> writes:
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
next sibling parent Kevin Cox <kevincox.ca gmail.com> writes:
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 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
prev sibling next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
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:
 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.
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.
Jul 17 2012
prev sibling next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
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
parent "angel" <andrey.gelman gmail.com> writes:
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
prev sibling next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
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
next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Wednesday, July 18, 2012 00:03:25 bearophile wrote:
 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.
You could always use __FUNCTION__ in a string mixin, but that _is_ rather ugly. - Jonathan M Davis
Jul 17 2012
prev sibling parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Wednesday, July 18, 2012 00:03:25 bearophile wrote:
 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.
You could always use __FUNCTION__ in a string mixin, but that _is_ rather ugly. - Jonathan M Davis
Jul 17 2012
parent "angel" <andrey.gelman gmail.com> writes:
 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
prev sibling next sibling parent reply "Eyyub" <eyyub.pangearaion gmail.com> writes:
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
parent reply "Era Scarecrow" <rtcvb32 yahoo.com> writes:
On Tuesday, 17 July 2012 at 22:13:13 UTC, Eyyub wrote:
 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.
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...
Jul 17 2012
parent reply Kevin Cox <kevincox.ca gmail.com> writes:
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:
 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.
Mmm.. Why not an inner function to represent the recursive function? True
a '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.
Jul 17 2012
parent reply FeepingCreature <default_357-line yahoo.de> writes:
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:
 On Tuesday, 17 July 2012 at 22:13:13 UTC, Eyyub wrote:
 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.
Mmm.. Why not an inner function to represent the recursive function? True a '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.
Sadly, this collides with the return-type syntax already in place. auto f = function int(int i) { return 0; };
Jul 18 2012
parent reply Kevin Cox <kevincox.ca gmail.com> writes:
On Jul 18, 2012 6:20 AM, "FeepingCreature" <default_357-line yahoo.de>
wrote:
 On 07/18/12 01:05, Kevin Cox 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.
 Sadly, 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
parent "angel" <andrey.gelman gmail.com> writes:
 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
prev sibling next sibling parent reply "Mehrdad" <wfunction hotmail.com> writes:
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
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 07/19/2012 04:54 AM, Mehrdad wrote:
 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);
- 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.
Jul 19 2012
prev sibling parent reply "Nathan M. Swan" <nathanmswan gmail.com> writes:
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
parent reply "Rob T" <rob ucora.com> writes:
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
parent reply Ben Davis <entheh cantab.net> writes:
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
next sibling parent Ben Davis <entheh cantab.net> writes:
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
prev sibling parent reply "Rob T" <rob ucora.com> writes:
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
next sibling parent reply Ben Davis <entheh cantab.net> writes:
On 18/09/2012 22:21, Rob T wrote:
 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); }
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
parent reply "Rob T" <rob ucora.com> writes:
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
parent reply Jacob Carlborg <doob me.com> writes:
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
next sibling parent "Rob T" <rob ucora.com> writes:
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
prev sibling parent Ben Davis <entheh cantab.net> writes:
On 19/09/2012 08:24, Jacob Carlborg wrote:
 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.
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.)
 but this works

 writeln(__traits( identifier, main ));

 It seems that __traits(itentifier, ) and .stringof are two ways of
 getting access to the same information.
Hmm, it does seem that way, doesn't it?
 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.
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.
Sep 22 2012
prev sibling next sibling parent Jacob Carlborg <doob me.com> writes:
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
prev sibling parent reply Nick Treleaven <ntrel-public yahoo.co.uk> writes:
On 18/09/2012 22:21, Rob T wrote:
 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.
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.
Sep 22 2012
parent reply "Rob T" <rob ucora.com> writes:
 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
parent reply Ben Davis <entheh cantab.net> writes:
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
next sibling parent reply Philippe Sigaud <philippe.sigaud gmail.com> writes:
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
parent reply Ben Davis <entheh cantab.net> writes:
On 23/09/2012 20:58, Philippe Sigaud wrote:
 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!
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 :)
Sep 23 2012
parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
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
prev sibling parent reply "Rob T" <rob ucora.com> writes:
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
parent reply "Rob T" <rob ucora.com> writes:
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
parent Nick Treleaven <ntrel-public yahoo.co.uk> writes:
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