Jump to page: 1 2
Thread overview
Question about typeof(this)
Sep 07, 2010
Jacob Carlborg
Sep 07, 2010
Don
Sep 07, 2010
Jacob Carlborg
Sep 07, 2010
Don
Sep 10, 2010
Jacob Carlborg
Sep 10, 2010
Pelle
Sep 12, 2010
Jacob Carlborg
Sep 12, 2010
Jacob Carlborg
Sep 14, 2010
Don
Sep 07, 2010
Stanislav Blinov
Sep 07, 2010
Jacob Carlborg
Sep 07, 2010
Stanislav Blinov
September 07, 2010
I'm reading http://www.digitalmars.com/d/2.0/declaration.html#Typeof where it says:

"typeof(this) will generate the type of what this  would be in a non-static member function, even if not in a member function. "

From that I got the impression that the code below would print the same result, but it doesn't. It prints:

main.Bar
main.Foo

instead of:

main.Foo
main.Foo

Is this a bug or have I misunderstood the docs?


module main;

import std.stdio;

class Bar
{
	void method ()
	{
		writeln(typeid(typeof(this)));
		writeln(typeid(this));
	}
}

class Foo : Bar {}

void main ()
{
	auto foo = new Foo;
	foo.method;
}

-- 
/Jacob Carlborg
September 07, 2010
Jacob Carlborg wrote:
> I'm reading http://www.digitalmars.com/d/2.0/declaration.html#Typeof where it says:
> 
> "typeof(this) will generate the type of what this  would be in a non-static member function, even if not in a member function. "
> 
>  From that I got the impression that the code below would print the same result, but it doesn't. It prints:
> 
> main.Bar
> main.Foo
> 
> instead of:
> 
> main.Foo
> main.Foo
> 
> Is this a bug or have I misunderstood the docs?

typeof(this) gives the *compile-time* type of this. Inside Bar, it has to return 'Bar'.
typeid(this) gives the *runtime* type of this. So it can work that it's Bar is actually a Foo.


> 
> 
> module main;
> 
> import std.stdio;
> 
> class Bar
> {
>     void method ()
>     {
>         writeln(typeid(typeof(this)));
>         writeln(typeid(this));
>     }
> }
> 
> class Foo : Bar {}
> 
> void main ()
> {
>     auto foo = new Foo;
>     foo.method;
> }
> 
September 07, 2010
 07.09.2010 17:00, Jacob Carlborg пишет:
> I'm reading http://www.digitalmars.com/d/2.0/declaration.html#Typeof where it says:
>
> "typeof(this) will generate the type of what this would be in a non-static member function, even if not in a member function. "
>
> From that I got the impression that the code below would print the same result, but it doesn't. It prints:
>
> main.Bar
> main.Foo
>
> instead of:
>
> main.Foo
> main.Foo
>
> Is this a bug or have I misunderstood the docs?
>
>
> module main;
>
> import std.stdio;
>
> class Bar
> {
> void method ()
> {
> writeln(typeid(typeof(this)));
> writeln(typeid(this));
> }
> }
>
> class Foo : Bar {}
>
> void main ()
> {
> auto foo = new Foo;
> foo.method;
> }
>
I don't think it's a bug. More of it, Expressions page in the docs has your very same example in Typeid section.

Inside Bar.method, typeof(this) yields a type (Bar), and typeid for types gets you, well, typeid for types :) typeid(this), hovewer, should get typeinfo for most derived class, which it does.
September 07, 2010
On 2010-09-07 17:29, Don wrote:
> Jacob Carlborg wrote:
>> I'm reading http://www.digitalmars.com/d/2.0/declaration.html#Typeof
>> where it says:
>>
>> "typeof(this) will generate the type of what this would be in a
>> non-static member function, even if not in a member function. "
>>
>> From that I got the impression that the code below would print the
>> same result, but it doesn't. It prints:
>>
>> main.Bar
>> main.Foo
>>
>> instead of:
>>
>> main.Foo
>> main.Foo
>>
>> Is this a bug or have I misunderstood the docs?
>
> typeof(this) gives the *compile-time* type of this. Inside Bar, it has
> to return 'Bar'.
> typeid(this) gives the *runtime* type of this. So it can work that it's
> Bar is actually a Foo.

I know that typeof(this) is a compile time expression but in this case I think the compiler has all the necessary information at compile time. Note that I'm not calling "method" on a base class reference, I'm calling it on the static type "Foo". In this case I think typeof(this) would resolve to the type of the receiver, i.e. the type of"foo".

>
>>
>>
>> module main;
>>
>> import std.stdio;
>>
>> class Bar
>> {
>> void method ()
>> {
>> writeln(typeid(typeof(this)));
>> writeln(typeid(this));
>> }
>> }
>>
>> class Foo : Bar {}
>>
>> void main ()
>> {
>> auto foo = new Foo;
>> foo.method;
>> }
>>


-- 
/Jacob Carlborg
September 07, 2010
On 2010-09-07 17:34, Stanislav Blinov wrote:
> 07.09.2010 17:00, Jacob Carlborg пишет:
>> I'm reading http://www.digitalmars.com/d/2.0/declaration.html#Typeof
>> where it says:
>>
>> "typeof(this) will generate the type of what this would be in a
>> non-static member function, even if not in a member function. "
>>
>> From that I got the impression that the code below would print the
>> same result, but it doesn't. It prints:
>>
>> main.Bar
>> main.Foo
>>
>> instead of:
>>
>> main.Foo
>> main.Foo
>>
>> Is this a bug or have I misunderstood the docs?
>>
>>
>> module main;
>>
>> import std.stdio;
>>
>> class Bar
>> {
>> void method ()
>> {
>> writeln(typeid(typeof(this)));
>> writeln(typeid(this));
>> }
>> }
>>
>> class Foo : Bar {}
>>
>> void main ()
>> {
>> auto foo = new Foo;
>> foo.method;
>> }
>>
> I don't think it's a bug. More of it, Expressions page in the docs has
> your very same example in Typeid section.
>
> Inside Bar.method, typeof(this) yields a type (Bar), and typeid for
> types gets you, well, typeid for types :) typeid(this), hovewer, should
> get typeinfo for most derived class, which it does.

No it's not the same example. In the example on the Expressions page typeid is used on the static type A with the dynamic type B. I have both the static and dynamic type Foo. I think in my example the compiler have all the necessary information at compile time and typeof(this) would resolve to the type of the receiver, i.e. the type of "foo" which is Foo.

-- 
/Jacob Carlborg
September 07, 2010
Jacob Carlborg wrote:
> On 2010-09-07 17:34, Stanislav Blinov wrote:
>> 07.09.2010 17:00, Jacob Carlborg пишет:
>>> I'm reading http://www.digitalmars.com/d/2.0/declaration.html#Typeof
>>> where it says:
>>>
>>> "typeof(this) will generate the type of what this would be in a
>>> non-static member function, even if not in a member function. "
>>>
>>> From that I got the impression that the code below would print the
>>> same result, but it doesn't. It prints:
>>>
>>> main.Bar
>>> main.Foo
>>>
>>> instead of:
>>>
>>> main.Foo
>>> main.Foo
>>>
>>> Is this a bug or have I misunderstood the docs?
>>>
>>>
>>> module main;
>>>
>>> import std.stdio;
>>>
>>> class Bar
>>> {
>>> void method ()
>>> {
>>> writeln(typeid(typeof(this)));
>>> writeln(typeid(this));
>>> }
>>> }
>>>
>>> class Foo : Bar {}
>>>
>>> void main ()
>>> {
>>> auto foo = new Foo;
>>> foo.method;
>>> }
>>>
>> I don't think it's a bug. More of it, Expressions page in the docs has
>> your very same example in Typeid section.
>>
>> Inside Bar.method, typeof(this) yields a type (Bar), and typeid for
>> types gets you, well, typeid for types :) typeid(this), hovewer, should
>> get typeinfo for most derived class, which it does.
> 
> No it's not the same example. In the example on the Expressions page typeid is used on the static type A with the dynamic type B. I have both the static and dynamic type Foo. I think in my example the compiler have all the necessary information at compile time and typeof(this) would resolve to the type of the receiver, i.e. the type of "foo" which is Foo.
> 
I still don't see the difference. But even if there is one... It may be that in this particular case compiler may have sufficient information, but there are plenty of cases when it may not: e.g. class Foo is in a separate module or even separate library. After all, method actually has signature Bar.method(), not Foo.method().
September 07, 2010
Jacob Carlborg wrote:
> On 2010-09-07 17:29, Don wrote:
>> Jacob Carlborg wrote:
>>> I'm reading http://www.digitalmars.com/d/2.0/declaration.html#Typeof
>>> where it says:
>>>
>>> "typeof(this) will generate the type of what this would be in a
>>> non-static member function, even if not in a member function. "
>>>
>>> From that I got the impression that the code below would print the
>>> same result, but it doesn't. It prints:
>>>
>>> main.Bar
>>> main.Foo
>>>
>>> instead of:
>>>
>>> main.Foo
>>> main.Foo
>>>
>>> Is this a bug or have I misunderstood the docs?
>>
>> typeof(this) gives the *compile-time* type of this. Inside Bar, it has
>> to return 'Bar'.
>> typeid(this) gives the *runtime* type of this. So it can work that it's
>> Bar is actually a Foo.
> 
> I know that typeof(this) is a compile time expression but in this case I think the compiler has all the necessary information at compile time. Note that I'm not calling "method" on a base class reference, I'm calling it on the static type "Foo". In this case I think typeof(this) would resolve to the type of the receiver, i.e. the type of"foo".

Even though in this instance it could work out which derived class is being used, it's not allowed to use that information while compiling method(). There is only ONE function method(), and it has to work for Bar, and all classes derived from Bar.
September 10, 2010
On 2010-09-07 22:32, Don wrote:
> Jacob Carlborg wrote:
>> On 2010-09-07 17:29, Don wrote:
>>> Jacob Carlborg wrote:
>>>> I'm reading http://www.digitalmars.com/d/2.0/declaration.html#Typeof
>>>> where it says:
>>>>
>>>> "typeof(this) will generate the type of what this would be in a
>>>> non-static member function, even if not in a member function. "
>>>>
>>>> From that I got the impression that the code below would print the
>>>> same result, but it doesn't. It prints:
>>>>
>>>> main.Bar
>>>> main.Foo
>>>>
>>>> instead of:
>>>>
>>>> main.Foo
>>>> main.Foo
>>>>
>>>> Is this a bug or have I misunderstood the docs?
>>>
>>> typeof(this) gives the *compile-time* type of this. Inside Bar, it has
>>> to return 'Bar'.
>>> typeid(this) gives the *runtime* type of this. So it can work that it's
>>> Bar is actually a Foo.
>>
>> I know that typeof(this) is a compile time expression but in this case
>> I think the compiler has all the necessary information at compile
>> time. Note that I'm not calling "method" on a base class reference,
>> I'm calling it on the static type "Foo". In this case I think
>> typeof(this) would resolve to the type of the receiver, i.e. the type
>> of"foo".
>
> Even though in this instance it could work out which derived class is
> being used, it's not allowed to use that information while compiling
> method(). There is only ONE function method(), and it has to work for
> Bar, and all classes derived from Bar.

I think Scala can handle this problem, the following text is a snippet from a paper called "Scalable Component Abstractions" (link at the bottom), page 4 "Type selection and singleton types":

class C {
	protected var x = 0;
	def incr: this.type = { x = x + 1; this }
}

class D extends C {
	def decr: this.type = { x = x - 1; this }
}

"Then we can chain calls to the incr and decr method, as in

val d = new D; d.incr.decr;

Without the singleton type this.type, this would not have
been possible, since d.incr would be of type C, which does
not have a decr member. In that sense, this.type is similar
to (covariant uses of ) Kim Bruce's mytype construct [5]."

I'm not very familiar with Scala but the above code example seems to work as I want typeof(this) to work.

http://www.scala-lang.org/sites/default/files/odersky/ScalableComponent.pdf

-- 
/Jacob Carlborg
September 10, 2010
On 09/10/2010 03:20 PM, Jacob Carlborg wrote:
> On 2010-09-07 22:32, Don wrote:
>> Jacob Carlborg wrote:
>>> On 2010-09-07 17:29, Don wrote:
>>>> Jacob Carlborg wrote:
>>>>> I'm reading http://www.digitalmars.com/d/2.0/declaration.html#Typeof
>>>>> where it says:
>>>>>
>>>>> "typeof(this) will generate the type of what this would be in a
>>>>> non-static member function, even if not in a member function. "
>>>>>
>>>>> From that I got the impression that the code below would print the
>>>>> same result, but it doesn't. It prints:
>>>>>
>>>>> main.Bar
>>>>> main.Foo
>>>>>
>>>>> instead of:
>>>>>
>>>>> main.Foo
>>>>> main.Foo
>>>>>
>>>>> Is this a bug or have I misunderstood the docs?
>>>>
>>>> typeof(this) gives the *compile-time* type of this. Inside Bar, it has
>>>> to return 'Bar'.
>>>> typeid(this) gives the *runtime* type of this. So it can work that it's
>>>> Bar is actually a Foo.
>>>
>>> I know that typeof(this) is a compile time expression but in this case
>>> I think the compiler has all the necessary information at compile
>>> time. Note that I'm not calling "method" on a base class reference,
>>> I'm calling it on the static type "Foo". In this case I think
>>> typeof(this) would resolve to the type of the receiver, i.e. the type
>>> of"foo".
>>
>> Even though in this instance it could work out which derived class is
>> being used, it's not allowed to use that information while compiling
>> method(). There is only ONE function method(), and it has to work for
>> Bar, and all classes derived from Bar.
>
> I think Scala can handle this problem, the following text is a snippet
> from a paper called "Scalable Component Abstractions" (link at the
> bottom), page 4 "Type selection and singleton types":
>
> class C {
> protected var x = 0;
> def incr: this.type = { x = x + 1; this }
> }
>
> class D extends C {
> def decr: this.type = { x = x - 1; this }
> }
>
> "Then we can chain calls to the incr and decr method, as in
>
> val d = new D; d.incr.decr;
>
> Without the singleton type this.type, this would not have
> been possible, since d.incr would be of type C, which does
> not have a decr member. In that sense, this.type is similar
> to (covariant uses of ) Kim Bruce's mytype construct [5]."
>
> I'm not very familiar with Scala but the above code example seems to
> work as I want typeof(this) to work.
>
> http://www.scala-lang.org/sites/default/files/odersky/ScalableComponent.pdf
>

You can do this in D, but the syntax is clumsy. And it uses templates.

class C {
    int x;
    T incr(this T)() {
        x += 1;
        return cast(T)this; // clumsy, but always works (?)
    }
}
class D : C {
    T decr(this T)() {
        x -= 1;
        return cast(T)this;
    }
}

void main() {
    D d = new D;
    d.decr.incr.decr.incr.incr;
    writeln(d.x);

}
September 12, 2010
On 2010-09-10 16:53, Pelle wrote:
> On 09/10/2010 03:20 PM, Jacob Carlborg wrote:
>> On 2010-09-07 22:32, Don wrote:
>>> Jacob Carlborg wrote:
>>>> On 2010-09-07 17:29, Don wrote:
>>>>> Jacob Carlborg wrote:
>>>>>> I'm reading http://www.digitalmars.com/d/2.0/declaration.html#Typeof
>>>>>> where it says:
>>>>>>
>>>>>> "typeof(this) will generate the type of what this would be in a
>>>>>> non-static member function, even if not in a member function. "
>>>>>>
>>>>>> From that I got the impression that the code below would print the
>>>>>> same result, but it doesn't. It prints:
>>>>>>
>>>>>> main.Bar
>>>>>> main.Foo
>>>>>>
>>>>>> instead of:
>>>>>>
>>>>>> main.Foo
>>>>>> main.Foo
>>>>>>
>>>>>> Is this a bug or have I misunderstood the docs?
>>>>>
>>>>> typeof(this) gives the *compile-time* type of this. Inside Bar, it has
>>>>> to return 'Bar'.
>>>>> typeid(this) gives the *runtime* type of this. So it can work that
>>>>> it's
>>>>> Bar is actually a Foo.
>>>>
>>>> I know that typeof(this) is a compile time expression but in this case
>>>> I think the compiler has all the necessary information at compile
>>>> time. Note that I'm not calling "method" on a base class reference,
>>>> I'm calling it on the static type "Foo". In this case I think
>>>> typeof(this) would resolve to the type of the receiver, i.e. the type
>>>> of"foo".
>>>
>>> Even though in this instance it could work out which derived class is
>>> being used, it's not allowed to use that information while compiling
>>> method(). There is only ONE function method(), and it has to work for
>>> Bar, and all classes derived from Bar.
>>
>> I think Scala can handle this problem, the following text is a snippet
>> from a paper called "Scalable Component Abstractions" (link at the
>> bottom), page 4 "Type selection and singleton types":
>>
>> class C {
>> protected var x = 0;
>> def incr: this.type = { x = x + 1; this }
>> }
>>
>> class D extends C {
>> def decr: this.type = { x = x - 1; this }
>> }
>>
>> "Then we can chain calls to the incr and decr method, as in
>>
>> val d = new D; d.incr.decr;
>>
>> Without the singleton type this.type, this would not have
>> been possible, since d.incr would be of type C, which does
>> not have a decr member. In that sense, this.type is similar
>> to (covariant uses of ) Kim Bruce's mytype construct [5]."
>>
>> I'm not very familiar with Scala but the above code example seems to
>> work as I want typeof(this) to work.
>>
>> http://www.scala-lang.org/sites/default/files/odersky/ScalableComponent.pdf
>>
>>
>
> You can do this in D, but the syntax is clumsy. And it uses templates.
>
> class C {
> int x;
> T incr(this T)() {
> x += 1;
> return cast(T)this; // clumsy, but always works (?)
> }
> }
> class D : C {
> T decr(this T)() {
> x -= 1;
> return cast(T)this;
> }
> }
>
> void main() {
> D d = new D;
> d.decr.incr.decr.incr.incr;
> writeln(d.x);
>
> }

I had no idea about this, thanks. I don't like the templates but I guess it's better than nothing.

-- 
/Jacob Carlborg
« First   ‹ Prev
1 2