digitalmars.D - std.v2 builder pattern replacement
- monkyyy (63/63) Jul 22 2022 So today I was looking into builder patterns with opDispatch,
- ryuukk_ (12/12) Jul 22 2022 I feel like you are over complicating and over engineering it,
- monkyyy (3/6) Jul 22 2022 Fundmentally its ufcs-able with statement
- ryuukk_ (17/23) Jul 23 2022 It's stacks up, then it becomes a problem as you watch your build
- Salih Dincer (44/64) Jul 23 2022 This convenience function looks very useful. However, when I try,
- FeepingCreature (25/42) Jul 27 2022 This only works with constants; it cannot function when assigning
- monkyyy (24/25) Jul 27 2022 ```d
So today I was looking into builder patterns with opDispatch, complained about d's edge cases; throw out some ideas that snar told me instantly wouldn't work etc. etc. Anyway, the conclusion of this discussion is an idea for a pattern. ```d auto withMe(string mixin_,Me,T...)(Me me,T arg){ with(me){ mixin(mixin_); } import std.algorithm; static if(!mixin_.canFind("return")){ return me; } } auto withRefMe(string mixin_,Me,T...)(ref Me me,T arg){ with(me){ mixin(mixin_); } import std.algorithm; static if(!mixin_.canFind("return")){ return me; } } struct complextype{ bool isfoo,isbar,isfoobar; int i; float f; bool b; } struct point{ int x,y,xv,yv; } alias atZero=withMe!(q{return x==0 && y==0;},point); void main(){ import std.stdio; auto p=point(1,2,3,4); p.withRefMe!q{x=xv;y=yv;};//update a simple object p.writeln; p.atZero.writeln; p.withRefMe!q{x=0;y=0;}; p.atZero.writeln; auto foo=complextype().withMe!q{ isfoo=true; i=1337; }(); auto bar=complextype().withMe!q{ isbar=true; f=4.20; }; auto foobar=complextype().withMe!q{ isfoobar=true; b=true; }; writeln(foo); writeln(bar); writeln(foobar); } ``` At this moment I don't know how to have this compile ref and non ref at the same time. But I suggest something like this gets into std.v2 and everyone uses it rather than rolling a custom builder in the future
Jul 22 2022
I feel like you are over complicating and over engineering it, and builder pattern is overrated imo If we had (designated inits everywhere) https://forum.dlang.org/thread/bcfhuxjqppthigqppyid forum.dlang.org We could simply use the struct, with defaults, and that is it, compiler will optimize everything anyways, you got your better builder I personally never been a fan of using templates for the sake of using templates when the simple solution is at our hands, it makes the code harder to read, harder to write and it adds up to making your program slow to compile https://twitter.com/flohofwoe/status/1068589642767900672
Jul 22 2022
On Friday, 22 July 2022 at 21:00:49 UTC, ryuukk_ wrote:I feel like you are over complicating and over engineering it, and builder pattern is overrated imo to making your program slow to compileFundmentally its ufcs-able with statement And this isnt going to be a slow template
Jul 22 2022
On Friday, 22 July 2022 at 23:19:53 UTC, monkyyy wrote:On Friday, 22 July 2022 at 21:00:49 UTC, ryuukk_ wrote:It's stacks up, then it becomes a problem as you watch your build speed tank as you import things from `std`, wich is already in a bad spot imo I personally think the `std` should only focus on 4 core APIs - memory (allocators) - containers (datastructures) - i/o (networking, event loop, database driver) - filesystem (files/path) Anything else is maintenance burden When you pick up a language and look at using the `std` you don't search for build pattern templates, you check if it has networking stuff to write your app, and that's where Phobos is lacking and failing behind Builder pattern is local to your program That is why all these sumtype/nullable etc should not be in the std and should be builtins insteadI feel like you are over complicating and over engineering it, and builder pattern is overrated imo to making your program slow to compileFundmentally its ufcs-able with statement And this isnt going to be a slow template
Jul 23 2022
On Friday, 22 July 2022 at 19:06:05 UTC, monkyyy wrote:So today I was looking into builder patterns with opDispatch, complained about d's edge cases; throw out some ideas that snar told me instantly wouldn't work etc. etc. Anyway, the conclusion of this discussion is an idea for a pattern. ```d auto withMe(string mixin_,Me,T...)(Me me,T arg){ with(me){ mixin(mixin_); } import std.algorithm; static if(!mixin_.canFind("return")){ return me; } } auto foo=complextype().withMe!q{ isfoo=true; i=1337; }(); ```This convenience function looks very useful. However, when I try, initA and initB give the same result. Moreover, the classic C-style is much shorter and similar: ```d import std.stdio; struct Harf { char harf = 96; string toString() { return [harf]; } } enum { A = 97, B, C, D } enum a = Harf(A); enum b = Harf(B); auto withMe(string elements, Me, T...)(Me me, T arg){ with(me) mixin(elements); return me; } void main() { struct S { Harf[] hler; int[] nler; int n; } /* toggleCode: auto initA = S().withMe!q{ hler = [a, b]; nler = [1, 2]; n = 3; }; initA.writeln; /*/ S initB = { hler : [a, b], nler : [1, 2], n : 3 }; initB.writeln; //*/ } /* Prints: S([a, b], [1, 2], 3) */ ``` Respects... SDB 79
Jul 23 2022
On Friday, 22 July 2022 at 19:06:05 UTC, monkyyy wrote:So today I was looking into builder patterns with opDispatch, complained about d's edge cases; throw out some ideas that snar told me instantly wouldn't work etc. etc. Anyway, the conclusion of this discussion is an idea for a pattern. ```d ... auto foo=complextype().withMe!q{ isfoo=true; i=1337; }(); ... ``` At this moment I don't know how to have this compile ref and non ref at the same time. But I suggest something like this gets into std.v2 and everyone uses it rather than rolling a custom builder in the futureThis only works with constants; it cannot function when assigning variables from the callsite. You'd need something horrible like ```d int callerI = 1337; auto foo = mixin(complextype().withMe!q{ i = callerI; }); ``` This is what we use on our end: ```d import boilerplate; struct Test { bool isfoo; int i; mixin(GenerateThis); } ... void main() { int callerI = 1337; Test foo() { with (Test.Builder()) { isfoo = true; i = callerI; return value; } } } ``` It's not exactly compact, but it's the best I think can be done before named arguments.
Jul 27 2022
On Wednesday, 27 July 2022 at 09:15:28 UTC, FeepingCreature wrote:This only works with constants;```d auto withMe(string mixin_,Me,T...)(Me me,T arg){ with(me){ mixin(mixin_); } import std.algorithm; static if(!mixin_.canFind("return")){ return me; } } struct foo{ float f; int uselessfield=1337; bool b; } alias biuldfoo=withMe!(q{f=arg[1];b=arg[0];},foo,bool,float); void main(){ import std.stdio; bool t=true; float fourtwenty=4.20; foo().withMe!q{f=arg[1];b=arg[0];}(t,fourtwenty).writeln; foo().biuldfoo(t,fourtwenty).writeln; }```
Jul 27 2022