digitalmars.D.learn - Question about typeof(this)
- Jacob Carlborg (30/30) Sep 07 2010 I'm reading http://www.digitalmars.com/d/2.0/declaration.html#Typeof
- Don (5/46) Sep 07 2010 typeof(this) gives the *compile-time* type of this. Inside Bar, it has
- Jacob Carlborg (8/54) Sep 07 2010 I know that typeof(this) is a compile time expression but in this case I...
- Don (5/36) Sep 07 2010 Even though in this instance it could work out which derived class is
- Jacob Carlborg (22/59) Sep 10 2010 I think Scala can handle this problem, the following text is a snippet
- Pelle (20/78) Sep 10 2010 You can do this in D, but the syntax is clumsy. And it uses templates.
- Jacob Carlborg (5/94) Sep 12 2010 I had no idea about this, thanks. I don't like the templates but I guess...
- Jacob Carlborg (29/118) Sep 12 2010 I've done some testing with this template parameters and it actually
- Don (6/138) Sep 14 2010 There are only two ways to have the behaviour you want:
- Stanislav Blinov (6/34) Sep 07 2010 I don't think it's a bug. More of it, Expressions page in the docs has
- Jacob Carlborg (8/55) Sep 07 2010 No it's not the same example. In the example on the Expressions page
- Stanislav Blinov (6/62) Sep 07 2010 I still don't see the difference. But even if there is one... It may be
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
Sep 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; }
Sep 07 2010
On 2010-09-07 17:29, Don wrote:Jacob Carlborg wrote: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".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.-- /Jacob Carlborgmodule 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; }
Sep 07 2010
Jacob Carlborg wrote:On 2010-09-07 17:29, Don wrote: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.Jacob Carlborg wrote: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".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.
Sep 07 2010
On 2010-09-07 22:32, Don wrote:Jacob Carlborg wrote: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 CarlborgOn 2010-09-07 17:29, Don wrote: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.Jacob Carlborg wrote: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".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.
Sep 10 2010
On 09/10/2010 03:20 PM, Jacob Carlborg wrote:On 2010-09-07 22:32, Don wrote: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); }Jacob Carlborg wrote: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.pdfOn 2010-09-07 17:29, Don wrote: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.Jacob Carlborg wrote: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".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.
Sep 10 2010
On 2010-09-10 16:53, Pelle wrote:On 09/10/2010 03:20 PM, Jacob Carlborg wrote:I had no idea about this, thanks. I don't like the templates but I guess it's better than nothing. -- /Jacob CarlborgOn 2010-09-07 22:32, Don wrote: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); }Jacob Carlborg wrote: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.pdfOn 2010-09-07 17:29, Don wrote: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.Jacob Carlborg wrote: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".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.
Sep 12 2010
On 2010-09-10 16:53, Pelle wrote:On 09/10/2010 03:20 PM, Jacob Carlborg wrote:I've done some testing with this template parameters and it actually works as I want it to, but I don't understand why it has to be a template. Both templates and typeof are resolved at compile time so I don't understand why it can't work with typeof. I have this example now: module main; import std.stdio; class Base { void foo (this T) () { writeln(T.stringof); writeln(typeof(this).stringof); } } class Foo : Base { } void main() { auto foo = new Foo; foo.foo; } It will print: Foo Base To me this template parameters look unnecessary, typeof should be able to handle this. In the above "foo" method I think T should be equal to typeof(this). -- /Jacob CarlborgOn 2010-09-07 22:32, Don wrote: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); }Jacob Carlborg wrote: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.pdfOn 2010-09-07 17:29, Don wrote: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.Jacob Carlborg wrote: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".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.
Sep 12 2010
Jacob Carlborg wrote:On 2010-09-10 16:53, Pelle wrote:There are only two ways to have the behaviour you want: (1) make it a template, so that the function is duplicated for every derived class (that's what this solution is doing); OR (2) use runtime type information. Both of these have unacceptable consequences in general.On 09/10/2010 03:20 PM, Jacob Carlborg wrote:I've done some testing with this template parameters and it actually works as I want it to, but I don't understand why it has to be a template. Both templates and typeof are resolved at compile time so I don't understand why it can't work with typeof. I have this example now: module main; import std.stdio; class Base { void foo (this T) () { writeln(T.stringof); writeln(typeof(this).stringof); } } class Foo : Base { } void main() { auto foo = new Foo; foo.foo; } It will print: Foo Base To me this template parameters look unnecessary, typeof should be able to handle this. In the above "foo" method I think T should be equal to typeof(this).On 2010-09-07 22:32, Don wrote: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); }Jacob Carlborg wrote: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.pdfOn 2010-09-07 17:29, Don wrote: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.Jacob Carlborg wrote: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".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.
Sep 14 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.
Sep 07 2010
On 2010-09-07 17:34, Stanislav Blinov wrote:07.09.2010 17:00, Jacob Carlborg пишет: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 CarlborgI'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.
Sep 07 2010
Jacob Carlborg wrote:On 2010-09-07 17:34, Stanislav Blinov wrote: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().07.09.2010 17:00, Jacob Carlborg пишет: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'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.
Sep 07 2010