digitalmars.D - template this parameters for constructors
- Gor Gyolchanyan (74/74) Feb 20 2013 Template this parameters (
- Jacob Carlborg (4/44) Feb 20 2013 I haven't even thought about this use case. It would be so cool.
- Gor Gyolchanyan (14/66) Feb 20 2013 This would mean, that D can flawlessly mix together static and dynamic
- Timon Gehr (12/15) Feb 20 2013 According to the online documentation it seems like it should work:
- Gor Gyolchanyan (7/25) Feb 20 2013 http://d.puremagic.com/issues/show_bug.cgi?id=9551
- Jacob Carlborg (6/9) Feb 20 2013 You can't pass the static type to the base class, just as a workaround?
- Gor Gyolchanyan (9/20) Feb 20 2013 This adds boilerplate, that I can't afford. I need to transparently add
- Jacob Carlborg (7/12) Feb 20 2013 The compiler will make sure the a type is passed. You could add some
- kenji hara (8/41) Feb 20 2013 Constructor should check its qualifier as a switch to select constructio...
- Igor Stepanov (33/33) Feb 20 2013 What about template this for compile-time constructing of structs
Template this parameters ( http://dlang.org/template.html#TemplateThisParameter) are extremely useful for writing generic methods in base classes or interfaces that need to know the static type of the object they're called on. class Base { string label; this(string label_) { label = label_; } string toString(this This_)() { return This_.stringof ~ "(`" ~ label ~ "`)"; } } class Derived: Base { this() { super("Hello, world!"); } } unittest { Derived d = new Derived(); assert(d.toString() == "Derived(`Hello, world!`)"); } Of course, this wouldn't work if the toString() was called from a Base reference, instead of Derived. After I tested this, immediately thought of the constructor. The constructor of the base class is guaranteed to be called when constructing a derived class, right? Even if the call is implicit, it still happens and at the call site the concrete type being constructed is known, so in theory, a template this parameter on the base class's constructor should allow the base class to know the static type of the object being constructed (which is immensely useful for implementing dynamic dispatch classes). class Base { this(this This_)() { // Build a dispatch table using __traits(allMethods, This_) } void opCall(Payload_)(Payload_ payload_) { // Dynamically dispatch payload_ using the previously built dispatch table. } } class Derived: Base { // implicitly generated constructor will call the Base.this() and implicitly give it the static type of Derived. } unittest { Base b = new Derived; b(); // 100% transparent dynamic dispatch } Unfortunately, this is what DMD had to say about this: C:\Users\g.gyolchanyan\Desktop\test.d(3): Error: found 'This_' when expecting ')' C:\Users\g.gyolchanyan\Desktop\test.d(3): Error: semicolon expected following function declaration C:\Users\g.gyolchanyan\Desktop\test.d(3): Error: Declaration expected, not ')' It looks like DMD thinks I was gonna write a postblit constructor and I guess the functionality is already there, but can't be reached due to a parsing error. Is there any change of this being fixed any time soon? -- Bye, Gor Gyolchanyan.
Feb 20 2013
On 2013-02-20 15:37, Gor Gyolchanyan wrote:After I tested this, immediately thought of the constructor. The constructor of the base class is guaranteed to be called when constructing a derived class, right? Even if the call is implicit, it still happens and at the call site the concrete type being constructed is known, so in theory, a template this parameter on the base class's constructor should allow the base class to know the static type of the object being constructed (which is immensely useful for implementing dynamic dispatch classes). class Base { this(this This_)() { // Build a dispatch table using __traits(allMethods, This_) } void opCall(Payload_)(Payload_ payload_) { // Dynamically dispatch payload_ using the previously built dispatch table. } } class Derived: Base { // implicitly generated constructor will call the Base.this() and implicitly give it the static type of Derived. } unittest { Base b = new Derived; b(); // 100% transparent dynamic dispatch } Unfortunately, this is what DMD had to say about this: C:\Users\g.gyolchanyan\Desktop\test.d(3): Error: found 'This_' when expecting ')' C:\Users\g.gyolchanyan\Desktop\test.d(3): Error: semicolon expected following function declaration C:\Users\g.gyolchanyan\Desktop\test.d(3): Error: Declaration expected, not ')' It looks like DMD thinks I was gonna write a postblit constructor and I guess the functionality is already there, but can't be reached due to a parsing error.I haven't even thought about this use case. It would be so cool. -- /Jacob Carlborg
Feb 20 2013
On Wed, Feb 20, 2013 at 6:42 PM, Jacob Carlborg <doob me.com> wrote:On 2013-02-20 15:37, Gor Gyolchanyan wrote: After I tested this, immediately thought of the constructor. TheThis would mean, that D can flawlessly mix together static and dynamic typing to achieve maximum flexibility (using dynamic typing like this) and maximum performance (using static typing when this isn't required). No statically-typed and no dynamically-typed language can combine flexibility and performance right now. Combined with the upcoming revamp of D's compile-time and (built on top of it) run-time reflection, this will make D the ultimate modeling tool for building systems of arbitrary dynamicity and maximum performance. By the way, what's up with the new reflection thing that Andrei once wrote about? -- Bye, Gor Gyolchanyan.constructor of the base class is guaranteed to be called when constructing a derived class, right? Even if the call is implicit, it still happens and at the call site the concrete type being constructed is known, so in theory, a template this parameter on the base class's constructor should allow the base class to know the static type of the object being constructed (which is immensely useful for implementing dynamic dispatch classes). class Base { this(this This_)() { // Build a dispatch table using __traits(allMethods, This_) } void opCall(Payload_)(Payload_ payload_) { // Dynamically dispatch payload_ using the previously built dispatch table. } } class Derived: Base { // implicitly generated constructor will call the Base.this() and implicitly give it the static type of Derived. } unittest { Base b = new Derived; b(); // 100% transparent dynamic dispatch } Unfortunately, this is what DMD had to say about this: C:\Users\g.gyolchanyan\**Desktop\test.d(3): Error: found 'This_' when expecting ')' C:\Users\g.gyolchanyan\**Desktop\test.d(3): Error: semicolon expected following function declaration C:\Users\g.gyolchanyan\**Desktop\test.d(3): Error: Declaration expected, not ')' It looks like DMD thinks I was gonna write a postblit constructor and I guess the functionality is already there, but can't be reached due to a parsing error.I haven't even thought about this use case. It would be so cool. -- /Jacob Carlborg
Feb 20 2013
On 02/20/2013 03:37 PM, Gor Gyolchanyan wrote:... Is there any change of this being fixed any time soon? ...According to the online documentation it seems like it should work: http://dlang.org/template.html#TemplateThisParameter states: "TemplateThisParameters are used in member function templates to pick up the type of the this reference." http://dlang.org/class.html states: Classes consist of: ... * member functions ... * Constructors I guess just post it to bugzilla.
Feb 20 2013
On Wed, Feb 20, 2013 at 7:29 PM, Timon Gehr <timon.gehr gmx.ch> wrote:On 02/20/2013 03:37 PM, Gor Gyolchanyan wrote:http://d.puremagic.com/issues/show_bug.cgi?id=9551 I really really hope this gets fixed soon, because my project is stuck because of this. -- Bye, Gor Gyolchanyan.... Is there any change of this being fixed any time soon? ...According to the online documentation it seems like it should work: http://dlang.org/template.**html#TemplateThisParameter<http://dlang.org/template.html#TemplateThisParameter>states: "TemplateThisParameters are used in member function templates to pick up the type of the this reference." http://dlang.org/class.html states: Classes consist of: ... * member functions ... * Constructors I guess just post it to bugzilla.
Feb 20 2013
On 2013-02-20 16:38, Gor Gyolchanyan wrote:http://d.puremagic.com/issues/show_bug.cgi?id=9551 I really really hope this gets fixed soon, because my project is stuck because of this.You can't pass the static type to the base class, just as a workaround? class Base (T) { } class Sub : Base!(Sub) { } -- /Jacob Carlborg
Feb 20 2013
This adds boilerplate, that I can't afford. I need to transparently add dynamic dispatch to classes and I can't modify all of them. Besides, I have had experience with this previously and it causes a ton of problems, because there's no way of making sure the static type is passed and its' the right one. On Wed, Feb 20, 2013 at 7:46 PM, Jacob Carlborg <doob me.com> wrote:On 2013-02-20 16:38, Gor Gyolchanyan wrote: http://d.puremagic.com/issues/**show_bug.cgi?id=9551<http://d.puremagic.com/issues/show_bug.cgi?id=9551>-- Bye, Gor Gyolchanyan.I really really hope this gets fixed soon, because my project is stuck because of this.You can't pass the static type to the base class, just as a workaround? class Base (T) { } class Sub : Base!(Sub) { } -- /Jacob Carlborg
Feb 20 2013
On 2013-02-20 16:56, Gor Gyolchanyan wrote:This adds boilerplate, that I can't afford. I need to transparently add dynamic dispatch to classes and I can't modify all of them. Besides, I have had experience with this previously and it causes a ton of problems, because there's no way of making sure the static type is passed and its' the right one.The compiler will make sure the a type is passed. You could add some constraints on the template type but it wouldn't be 100% bulletproof. class Base (T : Base) { } class Sub : Base!(Sub) { } -- /Jacob Carlborg
Feb 20 2013
Constructor should check its qualifier as a switch to select construction strategy. It is described in TDPL, but it has not been yet implemented. The combination of constructor and TemplateThisParameter would affect to that not-implemented feature. As a conclusion, its semantics is YET NOT DEFINED. (Similar thing exists with "inout constructor". It is not also yet defined.) Kenji Hara 2013/2/21 Gor Gyolchanyan <gor.f.gyolchanyan gmail.com>On Wed, Feb 20, 2013 at 7:29 PM, Timon Gehr <timon.gehr gmx.ch> wrote:On 02/20/2013 03:37 PM, Gor Gyolchanyan wrote:http://d.puremagic.com/issues/show_bug.cgi?id=9551 I really really hope this gets fixed soon, because my project is stuck because of this. -- Bye, Gor Gyolchanyan.... Is there any change of this being fixed any time soon? ...According to the online documentation it seems like it should work: http://dlang.org/template.**html#TemplateThisParameter<http://dlang.org/template.html#TemplateThisParameter>states: "TemplateThisParameters are used in member function templates to pick up the type of the this reference." http://dlang.org/class.html states: Classes consist of: ... * member functions ... * Constructors I guess just post it to bugzilla.
Feb 20 2013
What about template this for compile-time constructing of structs (classes?)? e.g. struct BigDecimal { this(string arg) { *this = str2Dec(arg); } template this(string arg) { enum this = str2Dec(arg); } static BigDecimal str2Dec(string arg) //can be evaluated at compile time { //... } } void main() { string str = "42.24"; BigDecimal num1 = str;//Calling constructor BigDecimal.this BigDecimal num2 = "3,1415926535 8979323846 2643383279 5028841971 6939937510 5820974944 5923078164 0628620899 8628034825 3421170679 8214808651 3282306647 0938446095 5058223172 5359408128 4811174502 8410270193 8521105559 6446229489 5493038196 4428810975 6659334461 2847564823 3786783165 2712019091 4564856692 3460348610 4543266482 1339360726 0249141273 7245870066 0631558817 4881520920 9628292540 9171536436 7892590360 0113305305 4882046652 1384146951 9415116094 3305727036 5759591953 0921861173 8193261179"; //Calling template this at compile time. }
Feb 20 2013