digitalmars.D - RT/CT Type
- Alex (27/27) Apr 02 2019 Since D has a highly evolved meta programming and it should have
- Dennis (8/12) Apr 02 2019 Interesting idea. I heard Stefan Koch was working on a DIP for
- Jacob Carlborg (5/48) Apr 02 2019 I would much rather that D had first class types. That is, it would be
- Alex (5/54) Apr 02 2019 Sure, but that isn't likely to happen and probably will be far
- Paul Backus (9/13) Apr 02 2019 You cannot, in the general case, go back and forth freely between types
- pham (22/34) Apr 02 2019 Delphi has implemented class type for a long time. D should have
- Bastiaan Veelo (12/37) Apr 02 2019 Jacob is talking about "first class" types. D does support
- Bastiaan Veelo (23/39) Apr 02 2019 So in Delphi you can skip calling the constructor of the base
Since D has a highly evolved meta programming and it should have unitifed type that works two ways: 1. At CT, the type acts as an type or sorta like an alias. 2. At RT the type acts as a string. Type t = int; At compile time, t x; is the same at int x; At RT t = "int" Why is this important? The purpose is to unify certain CT and RT code. Because CTFE acts as runtime we might use it to build a type, but as a string, such as return getType(T)(T x) { return T.stringof; // CTFE/RT //return T // would be simpler } But then we could do getType(32) x; at CT. or use getType at runtime. This is a contrived example but I'm finding that I'm having to use CTFE to deal with types which requires strings and then convert those strings back in to types using string mixins, which is a PIBA.
Apr 02 2019
Interesting idea. I heard Stefan Koch was working on a DIP for first class types in D, you might be interested in that. I also know Zig has a 'comptime' keyword and first class types to do meta programming, which removes the explicit distinction between RT/CT parameter lists that D has. On Tuesday, 2 April 2019 at 07:48:23 UTC, Alex wrote:This is a contrived example but I'm finding that I'm having to use CTFE to deal with types which requires strings and then convert those strings back in to types using string mixins, which is a PIBA.Can you give your actual usecase? Your example is already doable with typeof().
Apr 02 2019
On 2019-04-02 09:48, Alex wrote:Since D has a highly evolved meta programming and it should have unitifed type that works two ways: 1. At CT, the type acts as an type or sorta like an alias. 2. At RT the type acts as a string. Type t = int; At compile time, t x; is the same at int x; At RT t = "int" Why is this important? The purpose is to unify certain CT and RT code. Because CTFE acts as runtime we might use it to build a type, but as a string, such as return getType(T)(T x) { return T.stringof; // CTFE/RT //return T // would be simpler } But then we could do getType(32) x; at CT. or use getType at runtime. This is a contrived example but I'm finding that I'm having to use CTFE to deal with types which requires strings and then convert those strings back in to types using string mixins, which is a PIBA.I would much rather that D had first class types. That is, it would be possible to store types in variables and in arrays and so on. -- /Jacob Carlborg
Apr 02 2019
On Tuesday, 2 April 2019 at 10:45:37 UTC, Jacob Carlborg wrote:On 2019-04-02 09:48, Alex wrote:Sure, but that isn't likely to happen and probably will be far more work. By simply having them convert to strings in RT helps a lot. When combined with CTFE and mixins it works well because one can go back and forth between type and strings.Since D has a highly evolved meta programming and it should have unitifed type that works two ways: 1. At CT, the type acts as an type or sorta like an alias. 2. At RT the type acts as a string. Type t = int; At compile time, t x; is the same at int x; At RT t = "int" Why is this important? The purpose is to unify certain CT and RT code. Because CTFE acts as runtime we might use it to build a type, but as a string, such as return getType(T)(T x) { return T.stringof; // CTFE/RT //return T // would be simpler } But then we could do getType(32) x; at CT. or use getType at runtime. This is a contrived example but I'm finding that I'm having to use CTFE to deal with types which requires strings and then convert those strings back in to types using string mixins, which is a PIBA.I would much rather that D had first class types. That is, it would be possible to store types in variables and in arrays and so on.
Apr 02 2019
On 4/2/19 8:38 AM, Alex wrote:Sure, but that isn't likely to happen and probably will be far more work. By simply having them convert to strings in RT helps a lot. When combined with CTFE and mixins it works well because one can go back and forth between type and strings.You cannot, in the general case, go back and forth freely between types and strings using `mixin`. Converting a type to a string discards all of its context information, and there is no way to recover that information from the string alone. Example: https://run.dlang.io/is/EAzKUC Even if this particular issue were fixed (getType could return a fully-qualified name), there would still be the issue of Voldemort types, which can *never* be mixed-in, even with a fully-qualified name.
Apr 02 2019
On Tuesday, 2 April 2019 at 10:45:37 UTC, Jacob Carlborg wrote:On 2019-04-02 09:48, Alex wrote:Since D has a highly evolved meta programming and it should have unitifed type that works two ways:Delphi has implemented class type for a long time. D should have vision to implement it. However, D also needs to implement inherited constructor in order for it to work Skeleton sample in Delphi type A = class create() virtual // constructor writeln('A.create') B = class(A) create() override // constructor //inherited create() // call inherited constructor implement if needed writeln('B.create') ClassType = class of A; // Any class inherited from A can be used to set to this type ClassType x = A; var x1 = x.create() // output 'A.create' x = B x1 = x.create() // output 'B.create' Cheers PhamThis is a contrived example but I'm finding that I'm having to use CTFE to deal with types which requires strings and then convert those strings back in to types using string mixins, which is a PIBA.I would much rather that D had first class types. That is, it would be possible to store types in variables and in arrays and so on.
Apr 02 2019
On Tuesday, 2 April 2019 at 17:00:41 UTC, pham wrote:On Tuesday, 2 April 2019 at 10:45:37 UTC, Jacob Carlborg wrote:Jacob is talking about "first class" types. D does support classes just like Delphi does (https://dlang.org/spec/class.html): ---- If no call to constructors via this or super appear in a constructor, and the base class has a constructor, a call to super() is inserted at the beginning of the constructor. If there is no constructor for a class, but there is a constructor for the base class, a default constructor is implicitly generated with the form: this() { } ----I would much rather that D had first class types. That is, it would be possible to store types in variables and in arrays and so on.Delphi has implemented class type for a long time. D should have vision to implement it. However, D also needs to implement inherited constructor in order for it to work Skeleton sample in Delphi type A = class create() virtual // constructor writeln('A.create') B = class(A) create() override // constructor //inherited create() // call inherited constructor implement if needed writeln('B.create') ClassType = class of A; // Any class inherited from A can be used to set to this type ClassType x = A; var x1 = x.create() // output 'A.create' x = B x1 = x.create() // output 'B.create' Cheers Pham
Apr 02 2019
On Tuesday, 2 April 2019 at 17:00:41 UTC, pham wrote: [...]Skeleton sample in Delphi type A = class create() virtual // constructor writeln('A.create') B = class(A) create() override // constructor //inherited create() // call inherited constructor implement if needed writeln('B.create') ClassType = class of A; // Any class inherited from A can be used to set to this type ClassType x = A; var x1 = x.create() // output 'A.create' x = B x1 = x.create() // output 'B.create'So in Delphi you can skip calling the constructor of the base class if you omit `inherited create()`? That would be rather odd. D does the right thing: --- import std.stdio; class A { this() { writeln(__FUNCTION__); } } class B : A { this() { writeln(__FUNCTION__); } } void main() { A a = new A; // Output A.this a = new B; // Output A.this, B.this. } --- https://run.dlang.io/is/6b2T4D Bastiaan.
Apr 02 2019