November 12, 2009
On Thu, Nov 12, 2009 at 7:53 AM, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
> Bill Baxter wrote:
>>
>> On Mon, Nov 9, 2009 at 6:03 PM, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
>>>
>>> Bill Baxter wrote:
>>>>
>>>> On Mon, Nov 9, 2009 at 4:09 PM, Walter Bright <newshound1@digitalmars.com> wrote:
>>>>>
>>>>> Looks like Bill Baxter is giving a presentation on D Nov. 18!
>>>>>
>>>>> http://www.nwcpp.org/
>>>>
>>>> Yep, that's right, and I'd be quite grateful to you smart folks here if you could share your meta-programming favorites with me!   If you've got a real-world example of meta-programming in D that you think is particularly handy, then please send it my way
>>>>
>>>> I'm looking for small-but-useful things that are easy to explain, and make something easier than it would be otherwise.  Things like places where static if can save your butt,  or loop unrolling,  and passing code snippets to functions like in std.algorithm.
>>>>
>>>> Things like a compile-time raytracer or regexp parser (though quite cool!) are not what I'm after.  Too involved for a short talk.
>>>>
>>>> --bb
>>>
>>> std.random has code that checks the parameters of a congruential RNG
>>> during
>>> compilation. That's also an example in TDPL.
>>
>> This looks good.
>> Any chance you could send me the snippet of the book that explains the
>> rationale for what constitutes "proper linear congruential
>> parameters"?
>>
>> --bb
>
> It's been online for a while.
>
> http://erdani.com/tdpl/excerpt.pdf

Thanks, I guess I saw that at some point, but forgot what it contained.

--bb
November 12, 2009
Bill Baxter wrote:

...
> 
> This is almost just a preprocessor macro trick, except for this line:
>      mixin( FoldStringsOf!visitMethodOf( ["Sum", "Product"] ) );
> 
> The essence is to generate a bunch of methods from a list of names.  I was thinking to include a similar example from the world of 3d graphics, which is generating all the swizzles of a vector* (got the idea from Tom S.).  That's got the method generation from a list, but it also generates the list too.

Interesting. I noticed it's also possible to pass a module as an alias and to things with it, but haven't come across an example of where that would be used. Modules are almost something in D, but just not yet.

> Another way is to have a swizz member template that lets you do v.swiz("zyx").  That's arguably better in that you don't pay for it if you don't use it.  But being able to generate all the methods with D is still kinda spiffy.
> 
> * Most GPU languages (HLSL,glsl,Cg) have a swizzle syntax, such that
> for a float3 v;   v.zyx  gives you float3(v.z,v.y,v.x).  And this
> works for all suffixes.   v.xxx, v.xzy, etc.  Also for different
> numbers of components.   eg.  v.xz is float2(v.x,v.z).
> 
> --bb

swizzling is a neat example! I also have code that actually implements the visitor interface with stubs that print, throw or assert, but it's kind of hairy.

November 12, 2009
On Tue, Nov 10, 2009 at 1:27 AM, Bill Baxter <wbaxter@gmail.com> wrote:
> On Mon, Nov 9, 2009 at 4:09 PM, Walter Bright <newshound1@digitalmars.com> wrote:
>> Looks like Bill Baxter is giving a presentation on D Nov. 18!
>>
>> http://www.nwcpp.org/
>
> Yep, that's right, and I'd be quite grateful to you smart folks here if you could share your meta-programming favorites with me!   If you've got a real-world example of meta-programming in D that you think is particularly handy, then please send it my way
>
> I'm looking for small-but-useful things that are easy to explain, and make something easier than it would be otherwise.  Things like places where static if can save your butt,  or loop unrolling,  and passing code snippets to functions like in std.algorithm.
>
> Things like a compile-time raytracer or regexp parser (though quite cool!) are not what I'm after.  Too involved for a short talk.
>
> --bb
>

I think tuples are a good example of something that makes your life easier, lately I've been very fond of this little snippet:

>>>>>>>>>>>>>>>>>>>>>>

void delegate() Bind(Args...)(void delegate(Args) dg, Args args)
{
    struct Closure
    {
        Args arguments;
        void delegate(Args) callee;
        void call()
        {
            callee(arguments);
        }
    }

    auto c = new Closure;

    // foreach not strictly necessary, but ldc currently chokes on
just an assignment... I should fix that..
    foreach(i,a;args)
        c.arguments[i] = a;
    c.callee = dg;

    return &c.call;
}

class C
{
    void foo(int,float) {}
}

void main()
{
    auto c = new C;
    auto dg = Bind(&c.foo, 1, 2.0f);
    // register delegate somewhere
}

<<<<<<<<<<<<<<<<<<<<<<<<

Not sure if this gets easier in C++0x , haven't read up on that...

Nothing fancy, but it sure has made my life easier.

-Tomas
November 12, 2009
On Thu, Nov 12, 2009 at 10:46 AM, Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> wrote:
> On Tue, Nov 10, 2009 at 1:27 AM, Bill Baxter <wbaxter@gmail.com> wrote:
>> On Mon, Nov 9, 2009 at 4:09 PM, Walter Bright <newshound1@digitalmars.com> wrote:
>>> Looks like Bill Baxter is giving a presentation on D Nov. 18!
>>>
>>> http://www.nwcpp.org/
>>
>> Yep, that's right, and I'd be quite grateful to you smart folks here if you could share your meta-programming favorites with me!   If you've got a real-world example of meta-programming in D that you think is particularly handy, then please send it my way
>>
>> I'm looking for small-but-useful things that are easy to explain, and make something easier than it would be otherwise.  Things like places where static if can save your butt,  or loop unrolling,  and passing code snippets to functions like in std.algorithm.
>>
>> Things like a compile-time raytracer or regexp parser (though quite cool!) are not what I'm after.  Too involved for a short talk.
>>
>> --bb
>>
>
> I think tuples are a good example of something that makes your life easier, lately I've been very fond of this little snippet:
>
>>>>>>>>>>>>>>>>>>>>>>>
>
> void delegate() Bind(Args...)(void delegate(Args) dg, Args args)
> {
>    struct Closure
>    {
>        Args arguments;
>        void delegate(Args) callee;
>        void call()
>        {
>            callee(arguments);
>        }
>    }
>
>    auto c = new Closure;
>
>    // foreach not strictly necessary, but ldc currently chokes on
> just an assignment... I should fix that..
>    foreach(i,a;args)
>        c.arguments[i] = a;
>    c.callee = dg;
>
>    return &c.call;
> }
>
> class C
> {
>    void foo(int,float) {}
> }
>
> void main()
> {
>    auto c = new C;
>    auto dg = Bind(&c.foo, 1, 2.0f);
>    // register delegate somewhere
> }
>
> <<<<<<<<<<<<<<<<<<<<<<<<
>
> Not sure if this gets easier in C++0x , haven't read up on that...

I think it does.  C++0x has variadic templates.  And some kind of lambdas/closure thing.  So probably it can do something similar. Anyway, the meta- aspect of Bind seems kinda weak.  Certainly a nice use of variadic templates and closures, though.

--bb
November 13, 2009
Bill Baxter <wbaxter@gmail.com> wrote:

> On Mon, Nov 9, 2009 at 4:09 PM, Walter Bright <newshound1@digitalmars.com> wrote:
>> Looks like Bill Baxter is giving a presentation on D Nov. 18!
>>
>> http://www.nwcpp.org/
> 
> Yep, that's right, and I'd be quite grateful to you smart folks here if you could share your meta-programming favorites with me!   If you've got a real-world example of meta-programming in D that you think is particularly handy, then please send it my way
> 
> I'm looking for small-but-useful things that are easy to explain, and make something easier than it would be otherwise.  Things like places where static if can save your butt,  or loop unrolling,  and passing code snippets to functions like in std.algorithm.
> 
> Things like a compile-time raytracer or regexp parser (though quite cool!) are not what I'm after.  Too involved for a short talk.
> 
> --bb
> 

I've use the code below to generate wrappers for my hessian serialization implementation.

its not all absolutely necessary but is only 130 lines.

import std.stdio;
import std.typetuple;
import std.traits;
import std.metastrings;

string[] splitFuncs(string str) {
    string[] res;
    while (str.length > 0) {
        while (str.length > 0 && (' ' == str[0] || ',' == str[0])) {
            str = str[1..$];
        }
        int to = 0;
        for (; to < str.length && str[to] != ' ' && str[to] != ','; ++to) {}
        if (to > 0) {
            res ~= str[0..to];
            str = str[to..$];
        }
    }
    return res;
}

string MethodTypeTuple_mixin(alias a)(string[] methods) {
	string ret = "TypeTuple!("~ "typeof(&C.init."~methods[0]~")";
	foreach (method; methods[1..$]) {
		ret ~= ",typeof(&C.init."~method~")";
	}
	ret ~= ")";
	return ret;
}



// test case

class A {
	int a;
	this(int a) {
		this.a = a;
	}
	int getInt(string intname) {
		return a;
	}

	void setInt(int i) {
		a = i;
	}
	string getString(string s) {
		return s ~"1234";
	}
}


string ProxyMethods_mixin(alias C, string methodstr)() {
	string ret;
	foreach(i, t; mixin(MethodTypeTuple_mixin!(C)(splitFuncs(methodstr)))) {
		// output function header
		ret ~= "\t"~ReturnType!(t).stringof ~" "~ splitFuncs(methodstr)[i]~"(";
		// output first arg
		ret ~= ParameterTypeTuple!(t)[0].stringof~" arg";
		// output remainder of args
		foreach (j, t1; ParameterTypeTuple!(t)[1..$]) {
			ret ~= ","~t1.stringof~" arg"~std.metastrings.ToString!(j);
		}
		// output body
		ret ~= ") {\n";
		// output serialization code
		// send method name
		ret ~= "\t\twritefln(\"serialize docall id\"); // the method call byte
id\n";
		ret ~= "\t\t//serialize!(string)(\""~splitFuncs(methodstr)[i]~"\"); /+
the method name +/\n";
		// send args
		ret ~= "\t\t//serialize!("~ ParameterTypeTuple!(t)[0].stringof~")
(arg); /+ the first argument +/\n";
		foreach (j, t1; ParameterTypeTuple!(t)[1..$]) {
			ret ~= "\t\t//serialize!("~ t1.stringof ~")(arg"~ToString!(j)~"); /
+ argument "~ToString!(j)~" +/\n";
		}
		// receive return type
		static if (!is(ReturnType!(t) == void)) {
			pragma(msg, "WARNING: this will always result in Range violation
due to no real data. THIS IS JUST A DEMO");
			pragma(msg, "\t\t need to implement the actual send/receive");
			ret ~= "\t\t//return deserialize!("~ ReturnType!(t).stringof ~")
(buffer);\n";
			// this is just here to make it still compile even though I've
commented out the real deserialize return above
			static if (is(ReturnType!(t) == int)) {
				ret ~= "\t\treturn 0;\n";
			} else {
				ret ~= "\t\treturn \"\";\n";
			}
		}
		ret ~= "\t}\n";
	}
	return ret;
}


string ProxyClass_mixin(alias C, string methodstr)() {
	string ret = "new class { ubyte[] buffer;\n";
	ret ~= ProxyMethods_mixin!(C, methodstr)();
	ret ~= "}\n";
	pragma(msg, MethodTypeTuple_mixin!(C)(splitFuncs(methodstr)));

	return ret;
}

class ProxyClass(alias C, string methodstr) {
		ubyte[] buffer;
		this() { }
		mixin(ProxyMethods_mixin!(C,methodstr)());
}

/+ void serialize(T)(T value) {
	writefln("serialize");
}
T deserialize(T)() {
	writefln("deserialize");
	static if (is(T==int)) {
		return 1;
	} else
	return "asdf";
} +/

void main() {
	pragma(msg, ProxyClass_mixin!(A,cast(string)"getInt setInt")());
	writefln(ProxyClass_mixin!(A,cast(string)"getInt setInt")());

 	auto c = mixin(ProxyClass_mixin!(A,cast(string)"getInt setInt getString")
());
	//pragma(msg, typeof(c).stringof);

	writefln("c.getInt(\"adsf\"): "~ c.getString("asdf"));

	auto pc = new ProxyClass!(A, cast(string)"getInt setInt getString");
	writefln("ProxyClass: "~ pc.getString("asdf"));
}


November 13, 2009
On Thu, Nov 12, 2009 at 8:24 PM, Bill Baxter <wbaxter@gmail.com> wrote:
> On Thu, Nov 12, 2009 at 10:46 AM, Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> wrote:
>> On Tue, Nov 10, 2009 at 1:27 AM, Bill Baxter <wbaxter@gmail.com> wrote:
>>> On Mon, Nov 9, 2009 at 4:09 PM, Walter Bright <newshound1@digitalmars.com> wrote:
>>>> Looks like Bill Baxter is giving a presentation on D Nov. 18!
>>>>
>>>> http://www.nwcpp.org/
>>>
>>> Yep, that's right, and I'd be quite grateful to you smart folks here if you could share your meta-programming favorites with me!   If you've got a real-world example of meta-programming in D that you think is particularly handy, then please send it my way
>>>
>>> I'm looking for small-but-useful things that are easy to explain, and make something easier than it would be otherwise.  Things like places where static if can save your butt,  or loop unrolling,  and passing code snippets to functions like in std.algorithm.
>>>
>>> Things like a compile-time raytracer or regexp parser (though quite cool!) are not what I'm after.  Too involved for a short talk.
>>>
>>> --bb
>>>
>>
>> I think tuples are a good example of something that makes your life easier, lately I've been very fond of this little snippet:
>>
>>>>>>>>>>>>>>>>>>>>>>>>
>>
>> void delegate() Bind(Args...)(void delegate(Args) dg, Args args)
>> {
>>    struct Closure
>>    {
>>        Args arguments;
>>        void delegate(Args) callee;
>>        void call()
>>        {
>>            callee(arguments);
>>        }
>>    }
>>
>>    auto c = new Closure;
>>
>>    // foreach not strictly necessary, but ldc currently chokes on
>> just an assignment... I should fix that..
>>    foreach(i,a;args)
>>        c.arguments[i] = a;
>>    c.callee = dg;
>>
>>    return &c.call;
>> }
>>
>> class C
>> {
>>    void foo(int,float) {}
>> }
>>
>> void main()
>> {
>>    auto c = new C;
>>    auto dg = Bind(&c.foo, 1, 2.0f);
>>    // register delegate somewhere
>> }
>>
>> <<<<<<<<<<<<<<<<<<<<<<<<
>>
>> Not sure if this gets easier in C++0x , haven't read up on that...
>
> I think it does.  C++0x has variadic templates.  And some kind of lambdas/closure thing.  So probably it can do something similar. Anyway, the meta- aspect of Bind seems kinda weak.  Certainly a nice use of variadic templates and closures, though.
>
> --bb
>

Just read the Wikipedia entries on Metaprogramming and
Template_metaprogramming, I guess I wasn't really aware of the
difference.
Seems a lot harder to come up with small real-world snippets of the former.
November 13, 2009
On Fri, Nov 13, 2009 at 11:38 AM, Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> wrote:
> On Thu, Nov 12, 2009 at 8:24 PM, Bill Baxter <wbaxter@gmail.com> wrote:
>> On Thu, Nov 12, 2009 at 10:46 AM, Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> wrote:
>>> On Tue, Nov 10, 2009 at 1:27 AM, Bill Baxter <wbaxter@gmail.com> wrote:
>>>> On Mon, Nov 9, 2009 at 4:09 PM, Walter Bright <newshound1@digitalmars.com> wrote:
>>>>> Looks like Bill Baxter is giving a presentation on D Nov. 18!
>>>>>
>>>>> http://www.nwcpp.org/
>>>>
>>>> Yep, that's right, and I'd be quite grateful to you smart folks here if you could share your meta-programming favorites with me!   If you've got a real-world example of meta-programming in D that you think is particularly handy, then please send it my way
>>>>
>>>> I'm looking for small-but-useful things that are easy to explain, and make something easier than it would be otherwise.  Things like places where static if can save your butt,  or loop unrolling,  and passing code snippets to functions like in std.algorithm.
>>>>
>>>> Things like a compile-time raytracer or regexp parser (though quite cool!) are not what I'm after.  Too involved for a short talk.
>>>>
>>>> --bb
>>>>
>>>
>>> I think tuples are a good example of something that makes your life easier, lately I've been very fond of this little snippet:
>>>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>
>>> void delegate() Bind(Args...)(void delegate(Args) dg, Args args)
>>> {
>>>    struct Closure
>>>    {
>>>        Args arguments;
>>>        void delegate(Args) callee;
>>>        void call()
>>>        {
>>>            callee(arguments);
>>>        }
>>>    }
>>>
>>>    auto c = new Closure;
>>>
>>>    // foreach not strictly necessary, but ldc currently chokes on
>>> just an assignment... I should fix that..
>>>    foreach(i,a;args)
>>>        c.arguments[i] = a;
>>>    c.callee = dg;
>>>
>>>    return &c.call;
>>> }
>>>
>>> class C
>>> {
>>>    void foo(int,float) {}
>>> }
>>>
>>> void main()
>>> {
>>>    auto c = new C;
>>>    auto dg = Bind(&c.foo, 1, 2.0f);
>>>    // register delegate somewhere
>>> }
>>>
>>> <<<<<<<<<<<<<<<<<<<<<<<<
>>>
>>> Not sure if this gets easier in C++0x , haven't read up on that...
>>
>> I think it does.  C++0x has variadic templates.  And some kind of lambdas/closure thing.  So probably it can do something similar. Anyway, the meta- aspect of Bind seems kinda weak.  Certainly a nice use of variadic templates and closures, though.
>>
>> --bb
>>
>
> Just read the Wikipedia entries on Metaprogramming and
> Template_metaprogramming, I guess I wasn't really aware of the
> difference.
> Seems a lot harder to come up with small real-world snippets of the former.

The way I read it, template metaprogramming is a kind of
metaprogramming.  Metaprogramming using templates.
And ctfe/string-mixin metaprogramming are another, macro
metaprogramming another etc.
I think the phrase "template metaprogramming" just took particularly
strong hold because of C++ where templates are always required for
accomplishing pretty much any kind of metaprogramming.

--bb
November 19, 2009
Walter Bright wrote:
> Looks like Bill Baxter is giving a presentation on D Nov. 18!
> http://www.nwcpp.org/

And Bill did a great job!
November 22, 2009
nice work


November 24, 2009
Walter Bright wrote:

> Looks like Bill Baxter is giving a presentation on D Nov. 18!
> 
> http://www.nwcpp.org/

slides are there! Very pretty, I bet it was a fine presentation. The slides are informative, good examples.