December 13, 2010
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
December 14, 2010
I have done a fair bit of mixin coding using recursive templates (inspired by std.typecons). It was an amazing taste of what you can do in D, and I am delighted with the result - HEAPS of boiler-plate coding vanished before my eyes. However, the template code is virtually impossible to understand.

What you are suggesting here seems to be a way to dramatically reduce the complexity of code that generates source-code and mixes it in. I think something like that is needed before this mind-bogglingly powerful feature of D can realise its potential.

There is of course the worry that it could get so easy that everyone starts doing it, and we have (relatively) impenetrable code everywhere instead of just deep in the bowels of framework libraries.


On 14/12/10 07:07, Jacob Carlborg wrote:
> 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.
>


-- 
Graham St Jack

December 14, 2010
On Tue, 14 Dec 2010 09:30:46 +0200, Graham St Jack <Graham.StJack@internode.on.net> wrote:

> There is of course the worry that it could get so easy that everyone starts doing it, and we have (relatively) impenetrable code everywhere instead of just deep in the bowels of framework libraries.

TBH, I'm more excited by AST macros which I understood are planned for D3, as mentioned here:
http://s3.amazonaws.com/dconf2007/WalterAndrei.pdf
They seem to promise the power of mixins, but without the mess.

-- 
Best regards,
 Vladimir                            mailto:vladimir@thecybershadow.net
December 14, 2010
On 14/12/10 20:33, Vladimir Panteleev wrote:
> On Tue, 14 Dec 2010 09:30:46 +0200, Graham St Jack
> <Graham.StJack@internode.on.net> wrote:
>
>> There is of course the worry that it could get so easy that everyone
>> starts doing it, and we have (relatively) impenetrable code everywhere
>> instead of just deep in the bowels of framework libraries.
>
> TBH, I'm more excited by AST macros which I understood are planned for
> D3, as mentioned here:
> http://s3.amazonaws.com/dconf2007/WalterAndrei.pdf
> They seem to promise the power of mixins, but without the mess.
>

I took a look at the pdf, but couldn't see how the AST macros could come
close to the kinds of things that are possible (but difficult) with mixins. Is there more information somewhere?

Jacob, I can see how your proposed syntax would make simple mixins easier and clearer, but how would it do something more complex?

For example taking a classname and a bunch of field types and names, and turning it into a class definition complete with constructor from field values, constructor from an input stream, a method to write to an output stream, and const getters. Or maybe std.typecons.AutoImplement.


-- 
Graham St Jack
December 14, 2010
Graham St Jack wrote:
> On 14/12/10 20:33, Vladimir Panteleev wrote:
>> On Tue, 14 Dec 2010 09:30:46 +0200, Graham St Jack
>> <Graham.StJack@internode.on.net> wrote:
>>
>>> There is of course the worry that it could get so easy that everyone
>>> starts doing it, and we have (relatively) impenetrable code everywhere
>>> instead of just deep in the bowels of framework libraries.
>>
>> TBH, I'm more excited by AST macros which I understood are planned for
>> D3, as mentioned here:
>> http://s3.amazonaws.com/dconf2007/WalterAndrei.pdf
>> They seem to promise the power of mixins, but without the mess.
>>
> 
> I took a look at the pdf, but couldn't see how the AST macros could come
> close to the kinds of things that are possible (but difficult) with mixins. 

That fact was recognized at the conference, on the following day. As a result, AST macros were dropped from D2.

They need to roughly match string mixins in power.  At this stage, there is no proposal for how they should work.
December 14, 2010
On 2010-12-14 11:03, Vladimir Panteleev wrote:
> On Tue, 14 Dec 2010 09:30:46 +0200, Graham St Jack
> <Graham.StJack@internode.on.net> wrote:
>
>> There is of course the worry that it could get so easy that everyone
>> starts doing it, and we have (relatively) impenetrable code everywhere
>> instead of just deep in the bowels of framework libraries.
>
> TBH, I'm more excited by AST macros which I understood are planned for
> D3, as mentioned here:
> http://s3.amazonaws.com/dconf2007/WalterAndrei.pdf
> They seem to promise the power of mixins, but without the mess.

I would like to have AST macros too but I was think my suggestion was perhaps easier to implement, just some syntactic sugar.

-- 
/Jacob Carlborg
December 14, 2010
"Graham St Jack" <Graham.StJack@internode.on.net> wrote in message news:ie76ig$b2v$1@digitalmars.com...
>
> What you are suggesting here seems to be a way to dramatically reduce the complexity of code that generates source-code and mixes it in. I think something like that is needed before this mind-bogglingly powerful feature of D can realise its potential.
>

I think a decent string-template library could probably come very close to the proposal without needing any language changes at all:

string get_set(T, string name)()
{
     return
     q{
         @type _@name;

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

         @type @name (@type @name)
         {
             return _@name = @name;
         }
     }.replace( ["@type": T.stringof, "@name": name] );
}

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

There are definitely some things about the proposal that are better than with this, but I just wanted to point out that the value of the proposal should probably be evaluated against something roughly like the above rather than something that does a bunch of procedural string splicing.


December 14, 2010
On 2010-12-14 12:42, Graham St Jack wrote:
> On 14/12/10 20:33, Vladimir Panteleev wrote:
>> On Tue, 14 Dec 2010 09:30:46 +0200, Graham St Jack
>> <Graham.StJack@internode.on.net> wrote:
>>
>>> There is of course the worry that it could get so easy that everyone
>>> starts doing it, and we have (relatively) impenetrable code everywhere
>>> instead of just deep in the bowels of framework libraries.
>>
>> TBH, I'm more excited by AST macros which I understood are planned for
>> D3, as mentioned here:
>> http://s3.amazonaws.com/dconf2007/WalterAndrei.pdf
>> They seem to promise the power of mixins, but without the mess.
>>
>
> I took a look at the pdf, but couldn't see how the AST macros could come
> close to the kinds of things that are possible (but difficult) with
> mixins. Is there more information somewhere?
>
> Jacob, I can see how your proposed syntax would make simple mixins
> easier and clearer, but how would it do something more complex?

I don't know, do you have an example ?

> For example taking a classname and a bunch of field types and names, and
> turning it into a class definition complete with constructor from field
> values, constructor from an input stream, a method to write to an output
> stream, and const getters. Or maybe std.typecons.AutoImplement.

Could you post an example of how that mixin would be used and the code it would generate then I can see if I can translate it to my syntax. AutoImplement seems to just contain template mixins which is something else.

-- 
/Jacob Carlborg
December 14, 2010
On 2010-12-14 13:05, Don wrote:
> Graham St Jack wrote:
>> On 14/12/10 20:33, Vladimir Panteleev wrote:
>>> On Tue, 14 Dec 2010 09:30:46 +0200, Graham St Jack
>>> <Graham.StJack@internode.on.net> wrote:
>>>
>>>> There is of course the worry that it could get so easy that everyone
>>>> starts doing it, and we have (relatively) impenetrable code everywhere
>>>> instead of just deep in the bowels of framework libraries.
>>>
>>> TBH, I'm more excited by AST macros which I understood are planned for
>>> D3, as mentioned here:
>>> http://s3.amazonaws.com/dconf2007/WalterAndrei.pdf
>>> They seem to promise the power of mixins, but without the mess.
>>>
>>
>> I took a look at the pdf, but couldn't see how the AST macros could come
>> close to the kinds of things that are possible (but difficult) with
>> mixins.
>
> That fact was recognized at the conference, on the following day. As a
> result, AST macros were dropped from D2.

Do you have an example that would work with string mixins but not with AST macros?

> They need to roughly match string mixins in power. At this stage, there
> is no proposal for how they should work.

I think someone, Nick Sabalausky perhaps, suggested to have something like the hygiene macros in Nemerle: http://nemerle.org/wiki/index.php?title=Macros

-- 
/Jacob Carlborg
December 14, 2010
"Jacob Carlborg" <doob@me.com> wrote in message news:ie8dpq$kfg$2@digitalmars.com...
> On 2010-12-14 13:05, Don wrote:
>> Graham St Jack wrote:
>>> On 14/12/10 20:33, Vladimir Panteleev wrote:
>>>> On Tue, 14 Dec 2010 09:30:46 +0200, Graham St Jack <Graham.StJack@internode.on.net> wrote:
>>>>
>>>>> There is of course the worry that it could get so easy that everyone starts doing it, and we have (relatively) impenetrable code everywhere instead of just deep in the bowels of framework libraries.
>>>>
>>>> TBH, I'm more excited by AST macros which I understood are planned for
>>>> D3, as mentioned here:
>>>> http://s3.amazonaws.com/dconf2007/WalterAndrei.pdf
>>>> They seem to promise the power of mixins, but without the mess.
>>>>
>>>
>>> I took a look at the pdf, but couldn't see how the AST macros could come close to the kinds of things that are possible (but difficult) with mixins.
>>
>> That fact was recognized at the conference, on the following day. As a result, AST macros were dropped from D2.
>
> Do you have an example that would work with string mixins but not with AST macros?
>
>> They need to roughly match string mixins in power. At this stage, there is no proposal for how they should work.
>
> I think someone, Nick Sabalausky perhaps, suggested to have something like the hygiene macros in Nemerle: http://nemerle.org/wiki/index.php?title=Macros
>

Though I'm a huge D/systems-language/native-compiled guy, Nemerle's macros and pattern matching are two things I'm very jealous of and have made it very tempting to put up with the CLR for certain things.


« First   ‹ Prev
1 2 3 4 5 6
Top | Discussion index | About this forum | D home