Thread overview | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
September 07, 2010 Question about typeof(this) | ||||
---|---|---|---|---|
| ||||
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 Re: Question about typeof(this) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | 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 Re: Question about typeof(this) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | 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 Re: Question about typeof(this) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Don | 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 Re: Question about typeof(this) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stanislav Blinov | 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 Re: Question about typeof(this) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | 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 Re: Question about typeof(this) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | 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 Re: Question about typeof(this) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Don | 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 Re: Question about typeof(this) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | 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 Re: Question about typeof(this) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Pelle | 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 |
Copyright © 1999-2021 by the D Language Foundation