This is an idea I've been thinking of for a while, it's not a really suggestion (at least not yet) I just wanted to here what people think about it.

If we take a step back and look at what string mixins actually do or rather what they're used for, that would be: inserting a piece/block of code where the mixin expression is used. If we then take a look at how a block of code is represented in D (how you store it in variables and how you pass it around). It's not as a string which is used by the mixin expression, instead delegates are used to represent a block of code in D that can be passed around. Therefore this is my idea:

Add a new mixin operator "@" (1). When that operator is put in front of a function call it would behave as a string mixin. The function that is called needs to be CTFE and return a delegate or an array of delegates:

class Foo
{
    @get_set("int", "bar");
}

The above code would be the same as the following code:

class Foo
{
    mixin(get_set("int", "bar"));
}

If we now move to the declaration of "get_set" this is how it could look like:

void delegate () get_set (string type, string name)
{
    return
    {
        @type _...@name;

        @type @name ()
        {
            return _...@name;
        }

        @type @name (@type @name)
        {
            return _...@name = @name;
        }
    };
}

In the above code when "@" is used in the delegate literal it basically behaves like string interpolation, so "@type" would be replaced with the content of the "type" variable (2).

When the "get_set" function is called with the mixin symbol the content of the returned delegate is inserted where the call is made. If the function returns an array of delegates then the array would be unfolded and the content of all the delegates would be inserted.



Taking it one step further:

Allow the mixin syntax to be placed in front of most of the declarations and drop the need for string literals, commas and parentheses, basically allowing the following syntax:

class Foo
{
    @get_set int bar;
}

Would be translated into this:

class Foo
{
    @get_set!(int)("bar");
}

Maybe one could do something like this as well:

@singleton class Foo
{

}

void delegate () singleton (string name, void delegate () classBody)
{
    return { // a simple singleton implementation
        class @name
        {
            static @name instance;

            static this ()
            {
                instance = new @name;
            }

            private this () {}

            @classBody;
        }
    };
}

Above, in the last example, @classBody would insert the content of the delegate, basically the class body.

1. I will use "@" in this example because I think it looks good but it would probably conflict with @nothrow, @property and others.

2. I have no idea if this usage of the mixin symbol, "@", will conflict with the first usage.

--
/Jacob Carlborg

Reply via email to