Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
November 21, 2014 "Named parameter builder" pattern for template parameters | ||||
---|---|---|---|---|
| ||||
I trust everyone here knows about the "builder" pattern (http://en.wikipedia.org/wiki/Builder_pattern)? It can be very useful when the number of (optional) arguments in a function start to run rampant, and you know the user only wants to start setting a subset of these. D has phenomenal meta programming possibilities, and I see more and more templates taking more and more parameters. So I thought to myself, why not have a template builder pattern? I was able to throw this together: http://dpaste.dzfl.pl/366d1fc22c9c Which allows things like: alias MyContainerType = ContainerBuilder!int //.setUseGC!??? //Don't care about GCm use default. .setScan!false .setUSomeOtherThing!true .Type; I think this is hugely neat. I'm posting here both to share, and for "peer review feedback". I'm also wondering if there is prior "literature" about this, and if it's something we'd want more of in Phobos? |
November 21, 2014 Re: "Named parameter builder" pattern for template parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra Attachments: | On Fri, 21 Nov 2014 13:39:42 +0000 monarch_dodra via Digitalmars-d <digitalmars-d@puremagic.com> wrote: > D has phenomenal meta programming possibilities, and I see more and more templates taking more and more parameters. So I thought to myself, why not have a template builder pattern? i did something similar in my iv.writer (ctfe format string parser). once i got about ten argumnets to each template (and growing), i moved everything to structure. struct WrData { ... fields ... auto set(string name, T) (in T value) if (__traits(hasMember, this, name)) { __traits(getMember, this, name) = value; return this; } } and then i can pass the struct around, changing only the fields i want, in "pseudo-functional" style: template MyTpl!(WrData data) { ... MyTpl!(data.set!"field0"(value0).set!"field1"(value1)); } that was a real saver. but now i have to wait for GDC update, 'cause 2.065 frontend is not able to use structs as template args. |
November 21, 2014 Re: "Named parameter builder" pattern for template parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Friday, 21 November 2014 at 13:39:43 UTC, monarch_dodra wrote:
> I trust everyone here knows about the "builder" pattern
> (http://en.wikipedia.org/wiki/Builder_pattern)? It can be very
> useful when the number of (optional) arguments in a function
> start to run rampant, and you know the user only wants to start
> setting a subset of these.
>
> D has phenomenal meta programming possibilities, and I see more
> and more templates taking more and more parameters. So I thought
> to myself, why not have a template builder pattern?
>
> I was able to throw this together:
> http://dpaste.dzfl.pl/366d1fc22c9c
>
> Which allows things like:
> alias MyContainerType = ContainerBuilder!int
> //.setUseGC!??? //Don't care about GCm use default.
> .setScan!false
> .setUSomeOtherThing!true
> .Type;
>
> I think this is hugely neat. I'm posting here both to share, and
> for "peer review feedback".
>
> I'm also wondering if there is prior "literature" about this, and
> if it's something we'd want more of in Phobos?
That's pretty awesome. There have been several times where I've been put off adding template parameters when I really wanted to, simply because I didn't want to have long, hard-to-read parameter lists in user code.
Ideally I would like to be able to do this:
mixin TemplateBuilder!(MyType, PresetTemplateArgs) MyChoiceOfBuilderName;
where preset template args is optional and variadic, e.g. T in your example.
|
November 21, 2014 Re: "Named parameter builder" pattern for template parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to ketmar | On Friday, 21 November 2014 at 14:46:00 UTC, ketmar via Digitalmars-d wrote: > On Fri, 21 Nov 2014 13:39:42 +0000 > monarch_dodra via Digitalmars-d <digitalmars-d@puremagic.com> wrote: > >> D has phenomenal meta programming possibilities, and I see more >> and more templates taking more and more parameters. So I thought >> to myself, why not have a template builder pattern? > i did something similar in my iv.writer (ctfe format string parser). > once i got about ten argumnets to each template (and growing), i moved > everything to structure. > > struct WrData { > ... fields ... > > auto set(string name, T) (in T value) > if (__traits(hasMember, this, name)) > { > __traits(getMember, this, name) = value; > return this; > } > } > > and then i can pass the struct around, changing only the fields i want, > in "pseudo-functional" style: > > template MyTpl!(WrData data) { > ... > MyTpl!(data.set!"field0"(value0).set!"field1"(value1)); > } > > that was a real saver. but now i have to wait for GDC update, 'cause > 2.065 frontend is not able to use structs as template args. Hum, use a standard structure combined with CTFE to achieve the same goal. Smart. BTW, if you use opDispatch, you could probably have it as: MyTpl!(data.set_field0(value0).set_field1(value1)); Which may or may not read nicer, depending on how you look at it. With proper template overloading, you should even be able to implement this as a backwards compatible template. |
November 22, 2014 Re: "Named parameter builder" pattern for template parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On 11/21/14 14:39, monarch_dodra via Digitalmars-d wrote: > D has phenomenal meta programming possibilities [...] > alias MyContainerType = ContainerBuilder!int > //.setUseGC!??? //Don't care about GCm use default. > .setScan!false > .setUSomeOtherThing!true > .Type; > > I think this is hugely neat. I'm posting here both to share, and for "peer review feedback". You can just use a struct and D's phenomenal compile time programming possibilities. ;) struct fParms { int one = 1; string two = "one"; } alias fParm = TParm!fParms; auto f(alias P=fParm)() { // ... use P.$parm to access parameters ... pragma(msg, P.one, " ", P.two); } auto f2(alias P, A...)(A a) { f!P(); } auto f3(alias P, A...)(A a) { enum ALT = P.one = P.one+34; f!ALT(); } void main() { f(); f!(fParm.one=2)(); f!(fParm.two="three")(); enum a = "four"; f!((fParm.one=4).two=a)(); f!(fParm.one(4).two(a))(); enum b = "five"; f!(fParm.two=b)(); f!(fParm.one(6).two(b~"+1"))(); enum c = "seven"; f2!(fParm.two=c)(42); f3!(fParm.one=8)(42); } @property TParm(alias Parms)() { static struct FParm { private Parms _parms; template opDispatch(string M) { ref opDispatch(B)(B b) @property { mixin("_parms."~M) = b; return this; } auto opDispatch()() @property { return mixin("_parms."~M); } } } return FParm(); } artur |
November 23, 2014 Re: "Named parameter builder" pattern for template parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Friday, 21 November 2014 at 13:39:43 UTC, monarch_dodra wrote: > I trust everyone here knows about the "builder" pattern > (http://en.wikipedia.org/wiki/Builder_pattern)? It can be very > useful when the number of (optional) arguments in a function > start to run rampant, and you know the user only wants to start > setting a subset of these. > > D has phenomenal meta programming possibilities, and I see more > and more templates taking more and more parameters. So I thought > to myself, why not have a template builder pattern? > > I was able to throw this together: > http://dpaste.dzfl.pl/366d1fc22c9c > > Which allows things like: > alias MyContainerType = ContainerBuilder!int > //.setUseGC!??? //Don't care about GCm use default. > .setScan!false > .setUSomeOtherThing!true > .Type; > > I think this is hugely neat. I'm posting here both to share, and > for "peer review feedback". > > I'm also wondering if there is prior "literature" about this, and > if it's something we'd want more of in Phobos? In this blog post http://tomerfiliba.com/blog/dlang a syntax based on overloading opDollar and opDispatch is proposed for key/value pairs: alias MyContainerType = ContainerBuilder!int[ $.Scan=false, $.SomeOtherThing=true ].Type; I still can't make up my mind if it's brilliant or blasphemous. |
November 25, 2014 Re: "Named parameter builder" pattern for template parameters | ||||
---|---|---|---|---|
| ||||
Attachments: | On Sat, 22 Nov 2014 17:36:02 +0100
Artur Skawina via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> You can just use a struct and D's phenomenal compile time programming possibilities. ;)
heh. thank you, with `alias` and function instead of struct my compile-time formatted writter now works with both GDC and DMD. yay!
|
November 26, 2014 Re: "Named parameter builder" pattern for template parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Friday, 21 November 2014 at 13:39:43 UTC, monarch_dodra wrote:
> I trust everyone here knows about the "builder" pattern
> (http://en.wikipedia.org/wiki/Builder_pattern)? It can be very
> useful when the number of (optional) arguments in a function
> start to run rampant, and you know the user only wants to start
> setting a subset of these.
>
> D has phenomenal meta programming possibilities, and I see more
> and more templates taking more and more parameters. So I thought
> to myself, why not have a template builder pattern?
>
> I was able to throw this together:
> http://dpaste.dzfl.pl/366d1fc22c9c
>
> Which allows things like:
> alias MyContainerType = ContainerBuilder!int
> //.setUseGC!??? //Don't care about GCm use default.
> .setScan!false
> .setUSomeOtherThing!true
> .Type;
>
> I think this is hugely neat. I'm posting here both to share, and
> for "peer review feedback".
>
> I'm also wondering if there is prior "literature" about this, and
> if it's something we'd want more of in Phobos?
If D would support getting parameter names(currently does not work for lambdas) of lambdas we could have:
someConnect(host => "test", port => 7999);
Just a random thought :)
|
November 26, 2014 Re: "Named parameter builder" pattern for template parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robik | On Wednesday, 26 November 2014 at 17:42:07 UTC, Robik wrote: > If D would support getting parameter names(currently does not work for lambdas) of lambdas we could have: > > someConnect(host => "test", port => 7999); > > Just a random thought :) import std.stdio; import std.traits; void main() { //Prints a blank line writeln(ParameterIdentifierTuple!((int n) => n)); } That's an annoying limitation. I've submitted a bug for it. https://issues.dlang.org/show_bug.cgi?id=13780 |
Copyright © 1999-2021 by the D Language Foundation