Thread overview
Code repetition
May 27, 2018
Malte
May 27, 2018
Adam D. Ruppe
May 27, 2018
I have some code like

void foo()
{
    // setup stuff
    int x;
    scope(exit) something;

    //
    x = 34;
}

....


void foon()
{
    // setup stuff
    int x;
    scope(exit) something;

    //
}



All the setup stuff is virtually identical in each foo. There are slight differences such as a return value.


I would like to abstract the code code so that it can be handled in one place.

I have not found a way to do this in D. Template mixins do not work because of the arbitrary expressions. Putting the code in a template/function/lambda does not work because of the scopes which will be called when the main function exists.

A string mixin is too messy since it treats the code as a string losing all syntax highlighting, etc.

I'd love to have something like a template mixin where I can just do

mixin template fooSetup(ret)
{
    // setup stuff
    int x;
    scope(exit) something;

}


and

void foo()
{
   fooSetup(3);
}


void foo4()
{
   fooSetup(13);
}

and everything behave as it should. I'm guessing this is going to be impossible to achieve in D?

May 27, 2018
I guess I should have mentioned that basically this is like a C macro.

May 27, 2018
On Sunday, 27 May 2018 at 06:47:38 UTC, IntegratedDimensions wrote:
> A string mixin is too messy since it treats the code as a string losing all syntax highlighting, etc.
>
> I'd love to have something like a template mixin where I can just do
>
> mixin template fooSetup(ret)
> {
>     // setup stuff
>     int x;
>     scope(exit) something;
>
> }
>
>
> and
>
> void foo()
> {
>    fooSetup(3);
> }
>
>
> void foo4()
> {
>    fooSetup(13);
> }
>
> and everything behave as it should. I'm guessing this is going to be impossible to achieve in D?

Well, if you want to have the same power as Cs textual replacement, you need string mixins. Often you can replace it with templates, but that depends on the application. I would avoid it if you can though, but more for debugging and not because of syntax highlighting.

void main()
{
    import std.stdio;

    int y = 1;
    mixin(fooSetup(3));
    writeln("x is ",x);
    x = 5;
}

string fooSetup(int val) {
    import std.conv;

    return q{
        int x = }~val.to!string~q{;
        scope(exit) {
            writeln("x was ", x);
            writeln("y was ", y);
        }
    };
}
May 27, 2018
On Sunday, 27 May 2018 at 06:47:38 UTC, IntegratedDimensions wrote:
> Putting the code in a template/function/lambda does not work because of the scopes which will be called when the main function exists.

I think you might just be using the wrong kind of function.

---
import std.stdio;
// the helper does the setup then calls another function for specific stuff
void helper(void delegate(ref int) specialized) {
    // setup stuff
    int x;
    scope(exit) writeln("exit ", x);

    // specialized stuff abstracted out
    specialized(x);
}

void foo() {
	helper( (ref x) {
		x = 34;
	});
}

void main() {
	foo();
}
---

> A string mixin is too messy since it treats the code as a string losing all syntax highlighting, etc.

Configure your editor so the q{ code... } strings don't highlight as a string and you get that at least.
May 27, 2018
On Sunday, 27 May 2018 at 13:20:08 UTC, Adam D. Ruppe wrote:
> On Sunday, 27 May 2018 at 06:47:38 UTC, IntegratedDimensions wrote:
>> Putting the code in a template/function/lambda does not work because of the scopes which will be called when the main function exists.
>
> I think you might just be using the wrong kind of function.
>
> ---
> import std.stdio;
> // the helper does the setup then calls another function for specific stuff
> void helper(void delegate(ref int) specialized) {
>     // setup stuff
>     int x;
>     scope(exit) writeln("exit ", x);
>
>     // specialized stuff abstracted out
>     specialized(x);
> }
>
> void foo() {
> 	helper( (ref x) {
> 		x = 34;
> 	});
> }
>
> void main() {
> 	foo();
> }
> ---

Yeah, this should work. Was hoping there was just a simple way to pull the code out but I guess this provides the best alternative.

Thanks.