digitalmars.D.learn - Setting field of struct object
- Joel (21/21) Jan 22 I've been watching a video (YouTube - "Pipeline-oriented
- Joel (2/24) Jan 22 I've lost interest in the video, looks like horrible syntax (F#).
- Danilo (48/50) Jan 22 Nonetheless, this usually used with Objects (new class/struct
- Danilo (17/18) Jan 22 With latest D you can also just use named parameters:
- Menjanahary R. R. (2/9) May 14 Fluent Interface 😀
- zjh (9/26) Jan 22 VS:`C++`
- Joel (3/31) Jan 22 What about in D:
- Danilo (13/21) Jan 22 It's not much different in D. ;)
- FeepingCreature (13/41) Jan 22 D:
- zjh (7/14) Jan 22 C++ can achieve ultimate `simplicity` without violating `DRY`,
- zjh (3/5) Jan 22 It seems that D language is not `professional`.
- Bkoie (7/14) Jan 22 i think D module base system is fine wished some other lang had
- zjh (4/6) Jan 22 Stop being `unconventional` and quickly copy their `good things`.
- Bkoie (6/10) Jan 22 i mean there some truth but all look at this way
- ryuukk_ (10/24) Jan 22 I used to want this feature too, but i then got hit by a bug when
- ryuukk_ (3/3) Jan 22 I should note that it only took me 1 project to never want to
- zjh (13/14) Jan 22 D language used to have no `copy constructor`, isn't it now added
- Renato (13/27) Jan 25 You know you can use struct literals in initializers, right?
- zjh (8/8) Jan 25 On Thursday, 25 January 2024 at 08:46:34 UTC, Renato wrote:
- Anonymouse (77/94) Feb 01 I had reason to need this to work a while ago and `opDispatch`
I've been watching a video (YouTube - "Pipeline-oriented programming - Scott Wlaschin - NDC Porto 2023") with something like the following code. This only sets the first method call, so I'm wanting to know how to make this work, for the subsequent methods. ```d import std; struct Person { string name, email; ulong age; auto withName(string name) { this.name=name; return this; } auto withEmail(string email) { this.email=email; return this; } auto withAge(ulong age) { this.age=age; return this; } } void main() { Person p; p.withName("Tom").withEmail("joelcnz gmail.com").withAge(44); writeln(p); } ```
Jan 22
On Monday, 22 January 2024 at 08:27:36 UTC, Joel wrote:I've been watching a video (YouTube - "Pipeline-oriented programming - Scott Wlaschin - NDC Porto 2023") with something like the following code. This only sets the first method call, so I'm wanting to know how to make this work, for the subsequent methods. ```d import std; struct Person { string name, email; ulong age; auto withName(string name) { this.name=name; return this; } auto withEmail(string email) { this.email=email; return this; } auto withAge(ulong age) { this.age=age; return this; } } void main() { Person p; p.withName("Tom").withEmail("joelcnz gmail.com").withAge(44); writeln(p); } ```
Jan 22
On Monday, 22 January 2024 at 08:35:01 UTC, Joel wrote:I've lost interest in the video, looks like horrible syntaxNonetheless, this usually used with Objects (new class/struct instances), like so: ```d import std; struct Person { string name, email; ulong age; auto withName(string name) { this.name=name; return this; } auto withEmail(string email) { this.email=email; return this; } auto withAge(ulong age) { this.age=age; return this; } } void main() { auto p = (new Person).withName("Tom") .withEmail("joelcnz gmail.com") .withAge(44); writeln(p); } ``` If you convert it to a class, add an `static opCall` for initialization, and a toString() method, it's even nicer: ```d module app; import std; class Person { private string name, email; private ulong age; auto withName(string name) { this.name=name; return this; } auto withEmail(string email) { this.email=email; return this; } auto withAge(ulong age) { this.age=age; return this; } static Person opCall() => new Person(); override string toString() { return "Person{ name: "~name~", age: "~age.to!string~", email: "~email~" }"; } } void main() { auto p = Person() .withName("Tom") .withEmail("joelcnz gmail.com") .withAge(44); writeln(p); } ``` It's common OOP style in some frameworks.
Jan 22
On Monday, 22 January 2024 at 08:54:21 UTC, Danilo wrote:It's common OOP style in some frameworks.With latest D you can also just use named parameters: ```d import std; struct Person { /*private*/ string name, email; /*private*/ ulong age; } void main() { auto p = Person( name: "Tom", email: "joelcnz gmail.com", age: 44, ); writeln(p); } ```
Jan 22
On Monday, 22 January 2024 at 08:54:21 UTC, Danilo wrote:On Monday, 22 January 2024 at 08:35:01 UTC, Joel wrote:Fluent Interface 😀[...]Nonetheless, this usually used with Objects (new class/struct instances), like so: ```d import std; [...]
May 14
On Monday, 22 January 2024 at 08:27:36 UTC, Joel wrote:```d import std; struct Person { string name, email; ulong age; auto withName(string name) { this.name=name; return this; } auto withEmail(string email) { this.email=email; return this; } auto withAge(ulong age) { this.age=age; return this; } } void main() { Person p; p.withName("Tom").withEmail("joelcnz gmail.com").withAge(44); writeln(p); } ```VS:`C++` ```d struct Person { string name, email; ulong age; } Person a{"n","email",33}; ```
Jan 22
On Monday, 22 January 2024 at 08:54:54 UTC, zjh wrote:On Monday, 22 January 2024 at 08:27:36 UTC, Joel wrote:What about in D: auto a=Person(“n”, “email”, 33);```d import std; struct Person { string name, email; ulong age; auto withName(string name) { this.name=name; return this; } auto withEmail(string email) { this.email=email; return this; } auto withAge(ulong age) { this.age=age; return this; } } void main() { Person p; p.withName("Tom").withEmail("joelcnz gmail.com").withAge(44); writeln(p); } ```VS:`C++` ```d struct Person { string name, email; ulong age; } Person a{"n","email",33}; ```
Jan 22
On Monday, 22 January 2024 at 08:54:54 UTC, zjh wrote:VS:`C++` ```d struct Person { string name, email; ulong age; } Person a{"n","email",33}; ```It's not much different in D. ;) ```d import std; struct Person { string name, email; ulong age; } void main() { auto p = Person("Tom", "joelcnz gmail.com", 44); writeln(p); } ```
Jan 22
On Monday, 22 January 2024 at 08:54:54 UTC, zjh wrote:On Monday, 22 January 2024 at 08:27:36 UTC, Joel wrote:D: ```d import std.stdio; struct Person { string name, email; ulong age; } void main() { Person p = Person(name: "n", email: "email", age: 33); writefln!"%s"(p); } ``````d import std; struct Person { string name, email; ulong age; auto withName(string name) { this.name=name; return this; } auto withEmail(string email) { this.email=email; return this; } auto withAge(ulong age) { this.age=age; return this; } } void main() { Person p; p.withName("Tom").withEmail("joelcnz gmail.com").withAge(44); writeln(p); } ```VS:`C++` ```d struct Person { string name, email; ulong age; } Person a{"n","email",33}; ```
Jan 22
On Monday, 22 January 2024 at 08:54:54 UTC, zjh wrote:```d struct Person { string name, email; ulong age; } Person a{"n","email",33}; ```C++ can achieve ultimate `simplicity` without violating `DRY`, And here, D violates the `DRY` principle! Moreover, as the `package level, module level, class level, member level`, D language violates integrity. Because D has no `class level` limit. These are all not `serious states`.
Jan 22
On Monday, 22 January 2024 at 11:31:11 UTC, zjh wrote: D language violates integrity.Because D has no `class level` limit. These are all not `serious states`.It seems that D language is not `professional`.
Jan 22
On Monday, 22 January 2024 at 11:31:11 UTC, zjh wrote:On Monday, 22 January 2024 at 08:54:54 UTC, zjh wrote: C++ can achieve ultimate `simplicity` without violating `DRY`, And here, D violates the `DRY` principle! Moreover, as the `package level, module level, class level, member level`, D language violates integrity. Because D has no `class level` limit. These are all not `serious states`.i think D module base system is fine wished some other lang had the same you can avoid circular import ref. dry? well he can easily turn that into a generic config static factory which its look like hes trying to do. D is totally different from C++ in D you usually you wont construct the struct directly use alias as.
Jan 22
On Monday, 22 January 2024 at 15:14:32 UTC, Bkoie wrote:D is totally different from C++ in D you usually you wont construct the struct directly use alias as.Stop being `unconventional` and quickly copy their `good things`. Otherwise, the `development speed` of the D language is really `too slow`!
Jan 22
On Monday, 22 January 2024 at 15:49:30 UTC, zjh wrote:Stop being `unconventional` and quickly copy their `good things`. Otherwise, the `development speed` of the D language is really `too slow`!i mean there some truth but all look at this way rust has new or default to construct python ? can lead to garbage d from alias as etc...
Jan 22
On Monday, 22 January 2024 at 11:31:11 UTC, zjh wrote:On Monday, 22 January 2024 at 08:54:54 UTC, zjh wrote:I used to want this feature too, but i then got hit by a bug when i reordered the fields in the struct.. i don't want to deal with that stuff anymore But we now have named arguments, so this feature could be make use of it, it's similar with enums, perhaps one day this could be revived: https://github.com/dlang/DIPs/blob/e2ca557ab9d3e60305a37da0d5b58299e0a9de0e/DIPs/DIP1044.md There is even a working implementation: https://github.com/dlang/dmd/pull/14650```d struct Person { string name, email; ulong age; } Person a{"n","email",33}; ```C++ can achieve ultimate `simplicity` without violating `DRY`, And here, D violates the `DRY` principle! Moreover, as the `package level, module level, class level, member level`, D language violates integrity. Because D has no `class level` limit. These are all not `serious states`.
Jan 22
I should note that it only took me 1 project to never want to touch C++ again.. that must be telling something, either about the language, or me, or both lol
Jan 22
On Monday, 22 January 2024 at 15:33:01 UTC, ryuukk_ wrote:it only took me 1 project to never want to touch C++ again..D language used to have no `copy constructor`, isn't it now added in again? You have to admit the good aspects of `C++`. You should take a look at the `latest C++`. C++ has already learned many advantages of `D`, but D has not made `significant progress`! As a user, `C++` is really not much different from D, and even surpasses D `in many aspects`. `RAII `, `variable parameter` template, `coroutine, concept`, `value semantics`, very easy to understand. Moreover, the `inheritance` of C++ is very enjoyable to use in many aspects.
Jan 22
On Monday, 22 January 2024 at 15:45:45 UTC, zjh wrote:On Monday, 22 January 2024 at 15:33:01 UTC, ryuukk_ wrote:Sounds like you should be using C++. Why are you here?it only took me 1 project to never want to touch C++ again..D language used to have no `copy constructor`, isn't it now added in again? You have to admit the good aspects of `C++`. You should take a look at the `latest C++`. C++ has already learned many advantages of `D`, but D has not made `significant progress`! As a user, `C++` is really not much different from D, and even surpasses D `in many aspects`. `RAII `, `variable parameter` template, `coroutine, concept`, `value semantics`, very easy to understand. Moreover, the `inheritance` of C++ is very enjoyable to use in many aspects.
Jan 22
On Monday, 22 January 2024 at 15:47:23 UTC, bachmeier wrote:Sounds like you should be using C++. Why are you here?I spent `too much time` on D.
Jan 22
On Monday, 22 January 2024 at 15:51:37 UTC, zjh wrote:I spent `too much time` on D.And some of the inherent `drawbacks` of `C++` are too hateful.
Jan 22
On Monday, 22 January 2024 at 15:56:59 UTC, zjh wrote:On Monday, 22 January 2024 at 15:51:37 UTC, zjh wrote:It's a package deal. Everything in C++ is there because there were benefits when they added it, but those benefits came with downsides. D will end up in the same place if it emulates C++.I spent `too much time` on D.And some of the inherent `drawbacks` of `C++` are too hateful.
Jan 22
On Monday, 22 January 2024 at 11:31:11 UTC, zjh wrote:On Monday, 22 January 2024 at 08:54:54 UTC, zjh wrote:You know you can use struct literals in initializers, right? ```d import std.stdio; struct Person { string name, email; ulong age; } void main() { Person p = {name: "Joe", email: "joe example.com", age: 30}; writeln(p); } ``````d struct Person { string name, email; ulong age; } Person a{"n","email",33}; ```C++ can achieve ultimate `simplicity` without violating `DRY`, And here, D violates the `DRY` principle! Moreover, as the `package level, module level, class level, member level`, D language violates integrity. Because D has no `class level` limit. These are all not `serious states`.
Jan 25
On Thursday, 25 January 2024 at 08:46:34 UTC, Renato wrote: ```d void main() { Person p = { "Joe", "joe ab.com", 30}; writeln(p); } ``` I just tested it and it works. It's `great`!
Jan 25
On Monday, 22 January 2024 at 08:27:36 UTC, Joel wrote:```d import std; struct Person { string name, email; ulong age; auto withName(string name) { this.name=name; return this; } auto withEmail(string email) { this.email=email; return this; } auto withAge(ulong age) { this.age=age; return this; } } void main() { Person p; p.withName("Tom").withEmail("joelcnz gmail.com").withAge(44); writeln(p); } ```I had reason to need this to work a while ago and `opDispatch` came in very handy. I was able to cook up one that forwarded calls to other members in a struct, while returning `this` by ref, allowing for chaining calls. I use it with UDAs. (Scroll to the unit tests for examples.) ```d /++ Mixin template generating an `opDispatch` redirecting calls to members whose names match the passed variable string but with an underscore prepended. +/ mixin template UnderscoreOpDispatcher() { ref auto opDispatch(string var, T)(T value) { import std.traits : isArray, isAssociativeArray, isSomeString; enum realVar = '_' ~ var; alias V = typeof(mixin(realVar)); static if (isAssociativeArray!V) { // Doesn't work with AAs without library solutions } else static if (isArray!V && !isSomeString!V) { mixin(realVar) ~= value; } else { mixin(realVar) = value; } return this; } auto opDispatch(string var)() inout { enum realVar = '_' ~ var; return mixin(realVar); } } /// unittest { struct Foo { int _i; string _s; bool _b; string[] _add; alias wordList = _add; mixin UnderscoreOpDispatcher; } Foo f; f.i = 42; // f.opDispatch!"i"(42); f.s = "hello"; // f.opDispatch!"s"("hello"); f.b = true; // f.opDispatch!"b"(true); f.add("hello"); // f.opDispatch!"add"("hello"); f.add("world"); // f.opDispatch!"add"("world"); assert(f.i == 42); assert(f.s == "hello"); assert(f.b); assert(f.wordList == [ "hello", "world" ]); auto f2 = Foo() .i(9001) .s("world") .b(false) .add("hello") .add("world"); assert(f2.i == 9001); assert(f2.s == "world"); assert(!f2.b); assert(f2.wordList == [ "hello", "world" ]); } ``` You could trivially adapt it to use a `withName`, `withEmail` calling scheme instead of the underscore thing.
Feb 01