Thread overview
static `this`
Feb 08, 2015
Mike
Feb 08, 2015
Meta
Feb 08, 2015
Marc Schütz
Feb 08, 2015
Meta
Feb 08, 2015
Mike
February 08, 2015
I'm elevating this from D.Learn [1] because I think it needs some input from the language designers.

This code compiles and executes:
-----------------------------------
import std.stdio;

struct StaticRegister {
    static private uint _value;
    @property static uint value() { return _value; }
    @property static void value(uint v) { _value = v; }

    static alias value this;

    static void test() {
        writeln(this.stringof);
        writeln(typeof(this).stringof);
        writeln(this.value);
    }
}

void main(string[] s) {
    // works due to `alias value this`
    StaticRegister = 1;

    StaticRegister.test();
}
-----------------------------------

Output:
StaticRegister
StaticRegister
1



However, this code fails to compile:
-----------------------------------
struct StaticRegister {
    static void test() {
        assert(this is null);
    }
}

void main(string[] s) {
    StaticRegister.test();
}
-----------------------------------

Output:
test.d(5): Error: 'this' is only defined in non-static member functions, not test

To make things more confusing, Bug 380 [2] apparently provided a fix for `this` not evaluating in a static context, but it was a D1 bug and may not apply to D2.

Is `this` overloaded to mean "this class" in a static context or is `this` only valid in a non-static context.  Please clarify, and if it's a bug, help me understand so I can make an accurate and actionable bug report.

Thanks for the help,
Mike

[1] - "static alias this" thread on D.Learn - http://forum.dlang.org/post/xcnwuneclebuyqcjbkwu@forum.dlang.org
[2] - Bug 380 - https://issues.dlang.org/show_bug.cgi?id=380
February 08, 2015
On Sunday, 8 February 2015 at 00:31:42 UTC, Mike wrote:
> I'm elevating this from D.Learn [1] because I think it needs some input from the language designers.
>
> This code compiles and executes:
> -----------------------------------
> import std.stdio;
>
> struct StaticRegister {
>     static private uint _value;
>     @property static uint value() { return _value; }
>     @property static void value(uint v) { _value = v; }
>
>     static alias value this;
>
>     static void test() {
>         writeln(this.stringof);
>         writeln(typeof(this).stringof);
>         writeln(this.value);
>     }
> }
>
> void main(string[] s) {
>     // works due to `alias value this`
>     StaticRegister = 1;
>
>     StaticRegister.test();
> }
> -----------------------------------
>
> Output:
> StaticRegister
> StaticRegister
> 1

`this` should not exist within a static member function. The fact that this code compiles is probably a bug. `StaticRegister = 1` is almost definitely not intended behaviour, and I don't know about `static alias value this`.


> However, this code fails to compile:
> -----------------------------------
> struct StaticRegister {
>     static void test() {
>         assert(this is null);
>     }
> }
>
> void main(string[] s) {
>     StaticRegister.test();
> }
> -----------------------------------
>
> Output:
> test.d(5): Error: 'this' is only defined in non-static member functions, not test

This is correct behaviour.


> Is `this` overloaded to mean "this class" in a static context or is `this` only valid in a non-static context.  Please clarify, and if it's a bug, help me understand so I can make an accurate and actionable bug report.

`this` should only be valid in a non-static context, as far as I know. That's pretty much what static means: "there is no `this`".

February 08, 2015
On Sunday, 8 February 2015 at 01:57:55 UTC, Meta wrote:
> On Sunday, 8 February 2015 at 00:31:42 UTC, Mike wrote:
>> Is `this` overloaded to mean "this class" in a static context or is `this` only valid in a non-static context.  Please clarify, and if it's a bug, help me understand so I can make an accurate and actionable bug report.
>
> `this` should only be valid in a non-static context, as far as I know. That's pretty much what static means: "there is no `this`".

The following is a useful idiom for static factory methods:

    struct S {
        this(int x) {
        }

        static auto make(int x) {
            return typeof(this)(x);
        }
    }
February 08, 2015
On Sunday, 8 February 2015 at 13:13:18 UTC, Marc Schütz wrote:
> On Sunday, 8 February 2015 at 01:57:55 UTC, Meta wrote:
>> On Sunday, 8 February 2015 at 00:31:42 UTC, Mike wrote:
>>> Is `this` overloaded to mean "this class" in a static context or is `this` only valid in a non-static context.  Please clarify, and if it's a bug, help me understand so I can make an accurate and actionable bug report.
>>
>> `this` should only be valid in a non-static context, as far as I know. That's pretty much what static means: "there is no `this`".
>
> The following is a useful idiom for static factory methods:
>
>     struct S {
>         this(int x) {
>         }
>
>         static auto make(int x) {
>             return typeof(this)(x);
>         }
>     }

Okay, I forgot about that one. `typeof` is somewhat of a special case, though, since you can also do typeof(1/0) and get `int`.
February 08, 2015
On Sunday, 8 February 2015 at 13:13:18 UTC, Marc Schütz wrote:
> On Sunday, 8 February 2015 at 01:57:55 UTC, Meta wrote:
>> On Sunday, 8 February 2015 at 00:31:42 UTC, Mike wrote:
>>> Is `this` overloaded to mean "this class" in a static context or is `this` only valid in a non-static context.  Please clarify, and if it's a bug, help me understand so I can make an accurate and actionable bug report.
>>
>> `this` should only be valid in a non-static context, as far as I know. That's pretty much what static means: "there is no `this`".
>
> The following is a useful idiom for static factory methods:
>
>     struct S {
>         this(int x) {
>         }
>
>         static auto make(int x) {
>             return typeof(this)(x);
>         }
>     }

Yes, there are a few cases where `this` seems to be allowed in a static context, but is that by accident, or by design?

If by accident, then then we have a bug that, unfortunately, people may be using as a feature.  If by design, then there's still a bug because it doesn't work consistently.

The grammar specification [1] is silent about the semantics of `this` in a static context, and the examples show usage only in a non-static context.

So, my qustion still remains:  Does `this` mean "this class/struct" in a static context, or does `this` have no semantic meaning in a static context?

Mike

[1] - http://dlang.org/expression.html#this
February 09, 2015
On 2/8/15 5:54 PM, Mike wrote:
> On Sunday, 8 February 2015 at 13:13:18 UTC, Marc Schütz wrote:
>> On Sunday, 8 February 2015 at 01:57:55 UTC, Meta wrote:
>>> On Sunday, 8 February 2015 at 00:31:42 UTC, Mike wrote:
>>>> Is `this` overloaded to mean "this class" in a static context or is
>>>> `this` only valid in a non-static context.  Please clarify, and if
>>>> it's a bug, help me understand so I can make an accurate and
>>>> actionable bug report.
>>>
>>> `this` should only be valid in a non-static context, as far as I
>>> know. That's pretty much what static means: "there is no `this`".
>>
>> The following is a useful idiom for static factory methods:
>>
>>     struct S {
>>         this(int x) {
>>         }
>>
>>         static auto make(int x) {
>>             return typeof(this)(x);
>>         }
>>     }
>
> Yes, there are a few cases where `this` seems to be allowed in a static
> context, but is that by accident, or by design?

typeof(this) is supposed to work in a static context. I can't find the spec part that describes this, but it definitely is not a bug.

Everything else is a bug.

-Steve