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

September 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!
September 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:
>> 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 :)
September 24, 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 {}.
September 25, 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

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


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

1 2 3 4
Next ›   Last »