September 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
>>
>

September 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);
}


September 18, 2012
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 :)
September 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 :)


September 19, 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
September 19, 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
September 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
September 22, 2012
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.
September 22, 2012
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.
September 23, 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