digitalmars.D - Small suggestion for default constructors
- TheZipCreator (42/42) Jan 16 2023 Something I find quite annoying to do is to create a constructor
- Mike Parker (8/9) Jan 16 2023 There's a distinction. The default initializer for a struct is
- Paul Backus (22/28) Jan 19 2023 Almost. There is one situation where `T.init` and `T()` are
- Adam D Ruppe (17/18) Jan 16 2023 Try this out:
- TheZipCreator (6/25) Jan 17 2023 ooh, that's an interesting usage of `tupleof`. I didn't even know
- H. S. Teoh (7/17) Jan 17 2023 [...]
- =?UTF-8?Q?Ali_=c3=87ehreli?= (42/46) Jan 17 2023 Which can be mixed-in and can have default arguments:
- JN (10/12) Jan 17 2023 Yeah, it's something I miss greatly from D (named constructors
- Salih Dincer (35/38) Jan 17 2023 You might like monkyyy's withMe() mixin template...
Something I find quite annoying to do is to create a constructor that only sets the given properties. For example: ```d class Foo { int x; int y; int z; this(int x, int y, int z) { this.x = x; this.y = y; this.z = z; } } ``` For structs, it automatically generates a constructor, and it'd be nice if you could autogenerate constructors for classes too, kinda like this: ```d class Foo { int x; int y; int z; default this(int x, int y, int z); } ``` which would just be syntactic sugar for the former. this could also be used for structs too if you've already specified a constructor: ```d struct Vector3 { float x; float y; float z; this(Vector2 v) { x = v.x; y = v.y; } default this(float x, float y, float z); } ``` I feel like this would avoid a lot of boilerplate and make things more concise.
Jan 16 2023
On Tuesday, 17 January 2023 at 02:45:30 UTC, TheZipCreator wrote:For structs, it automatically generates a constructor, and it'dThere's a distinction. The default initializer for a struct is the `.init` value of each member. `T()` is not a default constructor, but a struct literal that's equivalent to `T.init`. The default initializer for classes is always null and we don't have class literals. I'm not arguing against your suggestion here. Just wanted to point out the distinction.
Jan 16 2023
On Tuesday, 17 January 2023 at 03:02:46 UTC, Mike Parker wrote:On Tuesday, 17 January 2023 at 02:45:30 UTC, TheZipCreator wrote:Almost. There is one situation where `T.init` and `T()` are different, and that's when `T` is a nested struct. ```d void main() { int n; struct S { int fun() { return ++n; } } auto s1 = S(); assert(s1.fun() == 1); // ok auto s2 = S.init; assert(s2.fun() == 2); // segmentation fault } ``` In the above code, using `S()` initializes `s1`'s context pointer at runtime to point to `main`'s stack frame, allowing `s1.fun` to access the variable `n`. Using `S.init` to initialize `s2`, however, sets the context pointer to `null`, so when `s2.fun` is called, the program crashes.For structs, it automatically generates a constructor, and it'dThere's a distinction. The default initializer for a struct is the `.init` value of each member. `T()` is not a default constructor, but a struct literal that's equivalent to `T.init`.
Jan 19 2023
On Tuesday, 17 January 2023 at 02:45:30 UTC, TheZipCreator wrote:default this(float x, float y, float z);Try this out: class Foo { int x; int y; int z; // one little function this(typeof(this.tupleof) t) { this.tupleof = t; } } void main() { auto foo = new Foo(1, 2, 3); assert(foo.x == 1); assert(foo.y == 2); assert(foo.z == 3); }
Jan 16 2023
On Tuesday, 17 January 2023 at 03:12:09 UTC, Adam D Ruppe wrote:On Tuesday, 17 January 2023 at 02:45:30 UTC, TheZipCreator wrote:ooh, that's an interesting usage of `tupleof`. I didn't even know it could be used as an lvalue. This is a bit unclear if you don't know the internals of D though. also, this wouldn't work if you just want to initialize one or two values and not all of them, but still could be useful.default this(float x, float y, float z);Try this out: class Foo { int x; int y; int z; // one little function this(typeof(this.tupleof) t) { this.tupleof = t; } } void main() { auto foo = new Foo(1, 2, 3); assert(foo.x == 1); assert(foo.y == 2); assert(foo.z == 3); }
Jan 17 2023
On Tue, Jan 17, 2023 at 03:12:09AM +0000, Adam D Ruppe via Digitalmars-d wrote: [...]class Foo { int x; int y; int z; // one little function this(typeof(this.tupleof) t) { this.tupleof = t; } }[...] Very nice! Gotta use this in my own code sometime. :-D T -- Life is too short to run proprietary software. -- Bdale Garbee
Jan 17 2023
On 1/16/23 19:12, Adam D Ruppe wrote:// one little function this(typeof(this.tupleof) t) { this.tupleof = t; }Which can be mixed-in and can have default arguments: mixin template memberAssigningConstructor() { // one little function this(typeof(this.tupleof) t = typeof(this.tupleof).init) { this.tupleof = t; } } import std.stdio; class Foo { int x; int y; int z; mixin memberAssigningConstructor!(); override string toString() const { import std.format : format; return format!"%s %s %s"(x, y, z); } } void testWith(Args...)(Args args) { auto f = new Foo(args); writeln(f); } void main() { testWith(); testWith(1); testWith(1, 2); testWith(1, 2, 3); } Outputs: 0 0 0 1 0 0 1 2 0 1 2 3 However, I recommend testing compilation speeds because I used mixed-in tupleof for opCmp implementations in a project about 3 years ago. There were only 6 instances of that usage but the compilation times were noticeably affected. (Disclaimer: There were 6 instances but I think those modules were imported very many times by other modules.) Replacing the tupleof idiom with trivial functions fixed the compilation speed issue for me. Ali
Jan 17 2023
On Tuesday, 17 January 2023 at 02:45:30 UTC, TheZipCreator wrote:I feel like this would avoid a lot of boilerplate and make things more concise.Yeah, it's something I miss greatly from D (named constructors are another feature I miss). In Dart you can do it like this: class Point { num x; num y; Point(this.x, this.y); } var p = Point(10.0, 20.0);
Jan 17 2023
On Tuesday, 17 January 2023 at 02:45:30 UTC, TheZipCreator wrote:For structs, it automatically generates a constructor, and it'd be nice if you could autogenerate constructors for classes too, kinda like this:You might like monkyyy's withMe() mixin template... **Source Link:** https://forum.dlang.org/post/ipgwqcnfxltoijavflro forum.dlang.org **Sample Print:** `S!(Letter)(ab, [10, 20], true)` ```d auto withMe(string elements, Me, T...)(Me me, T arg){ with(me) mixin(elements); return me; } enum { A = 97, B, C, D } enum a = Letter(A); enum b = Letter(B); struct Letter { char letter = 96; alias letter this; } import std.stdio; void main() { struct S(T) { T[] word; int[] nums; bool view; } auto test = S!Letter().withMe!q{ word = [a, b]; nums = [10, 20]; view = true; }; test.writeln; } ``` SDB 79
Jan 17 2023