Re: Metaprogramming in D : Some Real-world Examples

2009-11-24 Thread BCS

Hello Lutger,


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.



re: the slides, are they avalable in .ppt or pdf for us ludites?




Re: Metaprogramming in D : Some Real-world Examples

2009-11-22 Thread Long Chang
nice work


Re: Metaprogramming in D : Some Real-world Examples

2009-11-13 Thread rmcguire
Bill Baxter wbax...@gmail.com wrote:
 
 On Mon, Nov 9, 2009 at 4:09 PM, Walter Bright
 newshou...@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)());
  

Re: Metaprogramming in D : Some Real-world Examples

2009-11-13 Thread Bill Baxter
On Fri, Nov 13, 2009 at 11:38 AM, Tomas Lindquist Olsen
tomas.l.ol...@gmail.com wrote:
 On Thu, Nov 12, 2009 at 8:24 PM, Bill Baxter wbax...@gmail.com wrote:
 On Thu, Nov 12, 2009 at 10:46 AM, Tomas Lindquist Olsen
 tomas.l.ol...@gmail.com wrote:
 On Tue, Nov 10, 2009 at 1:27 AM, Bill Baxter wbax...@gmail.com wrote:
 On Mon, Nov 9, 2009 at 4:09 PM, Walter Bright
 newshou...@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


Re: Metaprogramming in D : Some Real-world Examples

2009-11-12 Thread Bill Baxter
On Mon, Nov 9, 2009 at 6:03 PM, Andrei Alexandrescu
seewebsiteforem...@erdani.org wrote:
 Bill Baxter wrote:

 On Mon, Nov 9, 2009 at 4:09 PM, Walter Bright
 newshou...@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


Re: Metaprogramming in D : Some Real-world Examples

2009-11-12 Thread Bill Baxter
2009/11/10 Denis Koroskin 2kor...@gmail.com:
 On Tue, 10 Nov 2009 03:27:20 +0300, Bill Baxter wbax...@gmail.com wrote:

 kprintf (a printf variant) in XoMB is a nice example imo. It accepts format
 as a template parameter, doing all the checks at compile-time (and more).

 http://github.com/xomboverlord/xomb-bare-bones/blob/6d924a9fd7cafe43aa50f38c0cd04c44187d4993/kernel/core/kprintf.d


Nice.  400 lines is a little long for this purpose, though.  Maybe a
somewhat simplified version that just replaces {} with template args
would be good.  I guess that's pretty much what std.metastrings.Format
does, just with %s instead of {}.

--bb


Re: Metaprogramming in D : Some Real-world Examples

2009-11-12 Thread Jacob Carlborg

On 11/11/09 17:58, grauzone wrote:

Andrei Alexandrescu wrote:

grauzone wrote:

Don wrote:

Christopher Wright wrote:

grauzone wrote:

You're not testing for types, you're testing if it compiles.
Inside the tested block of code, all sorts of things could go
wrong. You can't know if is(typeof(...)) really did what you
wanted, or if something broke.


You're testing, is everything inside that OK?. If you want to know
WHY it's wrong, you'd better make sure you're testing something simple.


Andrei's range lib uses it more in a way does this type support this
and that range interface?. Example:
http://dsource.org/projects/phobos/browser/trunk/phobos/std/range.d#L58


Then different isXxxRange are used by higher-order ranges in defining
refined interfaces depending on the interfaces offered by their inputs.


That means if one isXxxRange fails because the user maybe made a typo in
the needed range function, the code will silently do something else.

But my main problem is that the user just gets a does not match
template declaration compiler error when he messes up his range
interface. He's neither told that e.g. his range-related function
returns the wrong type, nor is there any other refined error message.


The check doesn't have to look like that. The check can be inside the 
template with static if and you can have several checks for different 
things and use static assert to output a error message that make sense.



Now what if we'd introduce some sort of interfaces for type checking at
compile time?

interface InputRange(T) {
void popFront();
bool empty();
T front();
}

struct MyRange : InputRange!(int) {
void popFront() { ... }

//compiler error goes here...
void empty() { ... }

int front() { ... }
}

(or something like this)

PS: there are two aspects to the problem: 1. even compile time duck
typing shares some of the problems of runtime duck typing, and 2.
utterly unhelpful error messages. If you wouldn't explicitly check the
interface with is(typeof()), the compiler's error messages would be even
worse because of 1.


I fail to see how that's terrible. I am very happy D has that feature
- no other statically-typed language has it, and it can be used to
great effect. Look e.g. at Chain:

http://dsource.org/projects/phobos/browser/trunk/phobos/std/range.d#L799

There, the uses of static if (is(...)) allow Chain to define as
capable an interface as its inputs allow.


Andrei




Re: Metaprogramming in D : Some Real-world Examples

2009-11-12 Thread Nick Sabalausky
Bill Baxter wbax...@gmail.com wrote in message 
news:mailman.337.1258023453.20261.digitalmars-d-annou...@puremagic.com...
Hi Nick,

Thanks for the response.  More below.

However, the unescape() function used in traceVal looks like it might
be a useful CTFE example.  Some kind of compile-time string
escaping/unescaping could definitely be a good example.

Heh, I tend to forget about that one. That's from the semitwist.util.text 
module, which I haven't worked with much in a long time, so there's probably 
a lot of WTFs spread through the module, and if you use something there as 
an example, you might need to clean it up a little. FWIW, that 
double-quote-string escaping/unescaping is built around ctfe_substitute 
which is in semitwist.util.ctfe (although Tango might have something 
similar by now).

 [various]

This is another one that C++ people would just throw macros at and
wonder what the big deal is.

Ah, yea, good point. Of course, we'd probably all take D's metaprogramming 
over preprocessor macros anyday, but I can definitely see their point.

 === Compile-time checking on types with non-identifier strings ===

That is kinda neat, I suppose you could even extend that to make the
list of valid tokens be a template parameter (either variadic, or
separated by some delimiter in one big string that then gets broken up
at runtime).  I guess you could pitch this as a baby step towards the
full-fledged compile-time parser.  Step 0 recognize valid tokens.


Interesting idea, yea. Might not be much help for the lib as I currently 
have it though, since I'm just spitting out the static-style language 
definitions from a tool that takes in a grammar and generates D code. 
Certainly something to keep in mind for future expansion though.

Thanks for writing all these up.

No prob! :)




Re: Metaprogramming in D : Some Real-world Examples

2009-11-12 Thread Nick Sabalausky
Nick Sabalausky a...@a.a wrote in message 
news:hdgt9q$vt...@digitalmars.com...
 Bill Baxter wbax...@gmail.com wrote in message 
 news:mailman.337.1258023453.20261.digitalmars-d-annou...@puremagic.com...
Hi Nick,

 === Compile-time checking on types with non-identifier strings ===

That is kinda neat, I suppose you could even extend that to make the
list of valid tokens be a template parameter (either variadic, or
separated by some delimiter in one big string that then gets broken up
at runtime).  I guess you could pitch this as a baby step towards the
full-fledged compile-time parser.  Step 0 recognize valid tokens.


 Interesting idea, yea. Might not be much help for the lib as I currently 
 have it though, since I'm just spitting out the static-style language 
 definitions from a tool that takes in a grammar and generates D code. 
 Certainly something to keep in mind for future expansion though.


One other idea I had for expanding on that NewStyle_StaticToken would be: 
Suppose a grammar had some sort of naming convention that, well, meant 
something within the context of that grammar. Then the application code 
could take something like process(Token!(foo) token) {...} and use 
compile-time string processing to do advanced pattern-matching on the 
token-name when selecting which token types to process a certain way (maybe 
it would have to be a static if or a templated instead of a basic function 
though). Not a fully fleshed-out idea, of course, but maybe the start of 
something. In fact, I think tango.util.Convert does something vaguely like 
that to look for conversion functions. 




Re: Metaprogramming in D : Some Real-world Examples

2009-11-12 Thread Jeremie Pelletier

Andrei Alexandrescu wrote:

grauzone wrote:

Don wrote:

Christopher Wright wrote:

grauzone wrote:
You're not testing for types, you're testing if it compiles. Inside 
the tested block of code, all sorts of things could go wrong. You 
can't know if is(typeof(...)) really did what you wanted, or if 
something broke.


You're testing, is everything inside that OK?. If you want to know 
WHY it's wrong, you'd better make sure you're testing something simple.


Andrei's range lib uses it more in a way does this type support this 
and that range interface?. Example: 
http://dsource.org/projects/phobos/browser/trunk/phobos/std/range.d#L58


Then different isXxxRange are used by higher-order ranges in defining 
refined interfaces depending on the interfaces offered by their inputs. 
I fail to see how that's terrible. I am very happy D has that feature - 
no other statically-typed language has it, and it can be used to great 
effect. Look e.g. at Chain:


http://dsource.org/projects/phobos/browser/trunk/phobos/std/range.d#L799

There, the uses of static if (is(...)) allow Chain to define as capable 
an interface as its inputs allow.



Andrei


I really like Andrei's range library, I use it all the time when I need 
to pass slices of generic types around, it really is more convenient 
than a pair of iterators.


The way I see ranges is as a form of interface without being bound to 
classes; its the only way to make structs and D arrays pass the 
isXxxRange traits.


The prototypes for using ranges then just go from:

void dosomething(T)(IForwardRange!T range) {}

to

void dosomething(Range)(Range range) if(isForwardRange!Range) {}

and it means the same thing, but you can't send a string to IForwardRange.


Re: Metaprogramming in D : Some Real-world Examples

2009-11-12 Thread Andrei Alexandrescu

Bill Baxter wrote:

On Mon, Nov 9, 2009 at 6:03 PM, Andrei Alexandrescu
seewebsiteforem...@erdani.org wrote:

Bill Baxter wrote:

On Mon, Nov 9, 2009 at 4:09 PM, Walter Bright
newshou...@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


Andrei


Re: Metaprogramming in D : Some Real-world Examples

2009-11-12 Thread Bill Baxter
On Thu, Nov 12, 2009 at 7:53 AM, Andrei Alexandrescu
seewebsiteforem...@erdani.org wrote:
 Bill Baxter wrote:

 On Mon, Nov 9, 2009 at 6:03 PM, Andrei Alexandrescu
 seewebsiteforem...@erdani.org wrote:

 Bill Baxter wrote:

 On Mon, Nov 9, 2009 at 4:09 PM, Walter Bright
 newshou...@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


Re: Metaprogramming in D : Some Real-world Examples

2009-11-12 Thread Lutger
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. 



Re: Metaprogramming in D : Some Real-world Examples

2009-11-12 Thread Tomas Lindquist Olsen
On Tue, Nov 10, 2009 at 1:27 AM, Bill Baxter wbax...@gmail.com wrote:
 On Mon, Nov 9, 2009 at 4:09 PM, Walter Bright
 newshou...@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


Re: Metaprogramming in D : Some Real-world Examples

2009-11-11 Thread grauzone

Andrei Alexandrescu wrote:

grauzone wrote:

Lars T. Kyllingstad wrote:

Jacob Carlborg wrote:

On 11/10/09 01:27, Bill Baxter wrote:

On Mon, Nov 9, 2009 at 4:09 PM, Walter Bright
newshou...@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


This is invaluable to me, which makes it possible to do some form of 
duck typing at compile time:


static if (is(typeof({
/* does this compile */
})))


There are forces at work (Don, that is) attempting to get rid of that 
very construct and replace it with something better:


http://www.digitalmars.com/d/archives/digitalmars/D/Proposal_Replace_traits_and_is_typeof_XXX_with_a_magic_namespace_._99914.html 



In my humble opinion, is(typeof({...})) is an ugly creature. I really 
don't think it should be put under a spotlight as a good example of D 
metaprogramming. If anything, please use __traits(compiles, {...}) 
instead.


Who cares about ugly syntax, if the idea is bad in the first place?


I think testing types during compilation isn't bad. Under what 
circumstances is it?


You're not testing for types, you're testing if it compiles. Inside the 
tested block of code, all sorts of things could go wrong. You can't know 
if is(typeof(...)) really did what you wanted, or if something broke. At 
least when you're doing more complex stuff with is(typeof), the danger 
of silent failures increases. Suppose the user makes an error in his 
custom range type by specifying a wrong return type (or whatever), and 
the range library just ignores his range-related function. Maybe that 
range function was optional, which will end in the range library 
seemingly ignoring his function. Can this be good? (I don't know if that 
case I described can even happen in your ranges lib, but I think this is 
a typical failure that could happen with is(typeof).)


This isn't even compiletime duck typing anymore, it's try-and-error 
built into the compiler. Even worse, now having semantically incorrect 
code in D sources is perfectly fine for weird reasons, and the compiler 
has to swallow some kinds of semantics errors.


Really, wouldn't some mechanism to explicitly check for compile time 
contracts better?


For me, this is some sort of metaprogramming WTF. This all makes me 
cringe. Sorry about that.



Andrei


Re: Metaprogramming in D : Some Real-world Examples

2009-11-11 Thread Don

Christopher Wright wrote:

grauzone wrote:
You're not testing for types, you're testing if it compiles. Inside 
the tested block of code, all sorts of things could go wrong. You 
can't know if is(typeof(...)) really did what you wanted, or if 
something broke.


You're testing, is everything inside that OK?. If you want to know WHY 
it's wrong, you'd better make sure you're testing something simple.


So it requires caution, and you want to keep the contents small. It's 
useful, but it requires caution.


I don't even think it particularly requires caution. If it passes, you 
know everything is OK. It's just that it's an all-or-nothing test.


IMHO, one of the best features of it, is that you can have negative 
compile-time unit tests. You can create tests which must be rejected at 
compile time. I don't know of any other clean way to do that.


Re: Metaprogramming in D : Some Real-world Examples

2009-11-11 Thread Andrei Alexandrescu

grauzone wrote:

Don wrote:

Christopher Wright wrote:

grauzone wrote:
You're not testing for types, you're testing if it compiles. Inside 
the tested block of code, all sorts of things could go wrong. You 
can't know if is(typeof(...)) really did what you wanted, or if 
something broke.


You're testing, is everything inside that OK?. If you want to know 
WHY it's wrong, you'd better make sure you're testing something simple.


Andrei's range lib uses it more in a way does this type support this 
and that range interface?. Example: 
http://dsource.org/projects/phobos/browser/trunk/phobos/std/range.d#L58


Then different isXxxRange are used by higher-order ranges in defining 
refined interfaces depending on the interfaces offered by their inputs. 
I fail to see how that's terrible. I am very happy D has that feature - 
no other statically-typed language has it, and it can be used to great 
effect. Look e.g. at Chain:


http://dsource.org/projects/phobos/browser/trunk/phobos/std/range.d#L799

There, the uses of static if (is(...)) allow Chain to define as capable 
an interface as its inputs allow.



Andrei


Re: Metaprogramming in D : Some Real-world Examples

2009-11-11 Thread grauzone

Andrei Alexandrescu wrote:

grauzone wrote:

Don wrote:

Christopher Wright wrote:

grauzone wrote:
You're not testing for types, you're testing if it compiles. Inside 
the tested block of code, all sorts of things could go wrong. You 
can't know if is(typeof(...)) really did what you wanted, or if 
something broke.


You're testing, is everything inside that OK?. If you want to know 
WHY it's wrong, you'd better make sure you're testing something simple.


Andrei's range lib uses it more in a way does this type support this 
and that range interface?. Example: 
http://dsource.org/projects/phobos/browser/trunk/phobos/std/range.d#L58


Then different isXxxRange are used by higher-order ranges in defining 
refined interfaces depending on the interfaces offered by their inputs. 


That means if one isXxxRange fails because the user maybe made a typo in 
the needed range function, the code will silently do something else.


But my main problem is that the user just gets a does not match 
template declaration compiler error when he messes up his range 
interface. He's neither told that e.g. his range-related function 
returns the wrong type, nor is there any other refined error message.


Now what if we'd introduce some sort of interfaces for type checking at 
compile time?


interface InputRange(T) {
void popFront();
bool empty();
T front();
}

struct MyRange : InputRange!(int) {
void popFront() { ... }

//compiler error goes here...
void empty() { ... }

int front() { ... }
}

(or something like this)

PS: there are two aspects to the problem: 1. even compile time duck 
typing shares some of the problems of runtime duck typing, and 2. 
utterly unhelpful error messages. If you wouldn't explicitly check the 
interface with is(typeof()), the compiler's error messages would be even 
worse because of 1.


I fail to see how that's terrible. I am very happy D has that feature - 
no other statically-typed language has it, and it can be used to great 
effect. Look e.g. at Chain:


http://dsource.org/projects/phobos/browser/trunk/phobos/std/range.d#L799

There, the uses of static if (is(...)) allow Chain to define as capable 
an interface as its inputs allow.



Andrei


Re: Metaprogramming in D : Some Real-world Examples

2009-11-10 Thread Denis Koroskin

On Tue, 10 Nov 2009 03:27:20 +0300, Bill Baxter wbax...@gmail.com wrote:


On Mon, Nov 9, 2009 at 4:09 PM, Walter Bright
newshou...@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


kprintf (a printf variant) in XoMB is a nice example imo. It accepts  
format as a template parameter, doing all the checks at compile-time (and  
more).


http://github.com/xomboverlord/xomb-bare-bones/blob/6d924a9fd7cafe43aa50f38c0cd04c44187d4993/kernel/core/kprintf.d

/* This template will generate code for printing and will do
 * all parsing of the format string at compile time
 *
 * USAGE:
 *   kprintf!(format string {specifier} ... )(args...);
 *
 * EXAMPLES:
 *   kprintf!(Integer: {})(10);
 *   kprintf!({!cls}Cleared the screen.)();
 *   kprintf!({!pos:2,3}At position (2,3))();
 *   kprintf!({!fg:LightBlue!bg:Gray}{})(25);
 *   kprintf!({!fg:Red}redness)();
 *   kprintf!({x} Hex!)(145);
 *   kprintf!(Curly Brace: {{)();
 *
 * COMMANDS:
 *   !cls - Clears the screen.
 *   !fg  - Sets the foreground color, see the Color enum
 *in kernel/dev/console.d.
 *   !bg  - Sets the background color, same as above.
 *   !pos - Moves the cursor to the x and y given, see example above.
 *
 * SPECIFIERS:
 *   {x}  - Prints the hex value.
 *   {u}  - Treats as unsigned.
 *   {}   - Prints common form.
 *
 * WHY IS IT COOL?
 *   - Compile time parsing of format strings
 *   - Type checking at compile time as well
 *   - That means it can tell you that you are dumb before you execute.
 *   - No need to specify type information.
 *
 *   - So we can do this and not care about the
 *  output of the function:
 *
 *   auto blah = someFunction();
 *   kprintf!(Some Arbitrary Info: {})(blah);
 *
 *  WOWWY WOW WOW!
 *
 */


Re: Metaprogramming in D : Some Real-world Examples

2009-11-10 Thread Jacob Carlborg

On 11/10/09 01:27, Bill Baxter wrote:

On Mon, Nov 9, 2009 at 4:09 PM, Walter Bright
newshou...@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


This is invaluable to me, which makes it possible to do some form of 
duck typing at compile time:


static if (is(typeof({
/* does this compile */
})))

Then I have some other things, not the most useful stuff but still usable:

Get the name of a function
Get the parameter names of a function
Get the field names of a class/struct
Get/set private fields of a class/struct outside the module
Call a function with named arguments
Then some templates that check if a type has a (class) method



Re: Metaprogramming in D : Some Real-world Examples

2009-11-10 Thread Lars T. Kyllingstad

Jacob Carlborg wrote:

On 11/10/09 01:27, Bill Baxter wrote:

On Mon, Nov 9, 2009 at 4:09 PM, Walter Bright
newshou...@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


This is invaluable to me, which makes it possible to do some form of 
duck typing at compile time:


static if (is(typeof({
/* does this compile */
})))


There are forces at work (Don, that is) attempting to get rid of that 
very construct and replace it with something better:


http://www.digitalmars.com/d/archives/digitalmars/D/Proposal_Replace_traits_and_is_typeof_XXX_with_a_magic_namespace_._99914.html

In my humble opinion, is(typeof({...})) is an ugly creature. I really 
don't think it should be put under a spotlight as a good example of D 
metaprogramming. If anything, please use __traits(compiles, {...}) instead.


-Lars


Re: Metaprogramming in D : Some Real-world Examples

2009-11-10 Thread Bill Baxter
On Tue, Nov 10, 2009 at 4:29 AM, Lars T. Kyllingstad
pub...@kyllingen.nospamnet wrote:
 Jacob Carlborg wrote:

 On 11/10/09 01:27, Bill Baxter wrote:

 On Mon, Nov 9, 2009 at 4:09 PM, Walter Bright
 newshou...@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

 This is invaluable to me, which makes it possible to do some form of duck
 typing at compile time:

 static if (is(typeof({
 /* does this compile */
 })))

 There are forces at work (Don, that is) attempting to get rid of that very
 construct and replace it with something better:

 http://www.digitalmars.com/d/archives/digitalmars/D/Proposal_Replace_traits_and_is_typeof_XXX_with_a_magic_namespace_._99914.html

 In my humble opinion, is(typeof({...})) is an ugly creature. I really don't
 think it should be put under a spotlight as a good example of D
 metaprogramming. If anything, please use __traits(compiles, {...}) instead.

I really liked the meta.compiles(...) or meta(compiles, ...) idea.

You're right though.  I would rather show things that look
deliberately designed to do the job nicely instead of things that look
like hacks.   Unfortunately, a lot of real-world D meta-programming
currently requires hacky-looking things.  So I can't really avoid them
all.

--bb


Re: Metaprogramming in D : Some Real-world Examples

2009-11-10 Thread Andrei Alexandrescu

grauzone wrote:

Lars T. Kyllingstad wrote:

Jacob Carlborg wrote:

On 11/10/09 01:27, Bill Baxter wrote:

On Mon, Nov 9, 2009 at 4:09 PM, Walter Bright
newshou...@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


This is invaluable to me, which makes it possible to do some form of 
duck typing at compile time:


static if (is(typeof({
/* does this compile */
})))


There are forces at work (Don, that is) attempting to get rid of that 
very construct and replace it with something better:


http://www.digitalmars.com/d/archives/digitalmars/D/Proposal_Replace_traits_and_is_typeof_XXX_with_a_magic_namespace_._99914.html 



In my humble opinion, is(typeof({...})) is an ugly creature. I really 
don't think it should be put under a spotlight as a good example of D 
metaprogramming. If anything, please use __traits(compiles, {...}) 
instead.


Who cares about ugly syntax, if the idea is bad in the first place?


I think testing types during compilation isn't bad. Under what 
circumstances is it?


Andrei


Re: Metaprogramming in D : Some Real-world Examples

2009-11-09 Thread Bill Baxter
On Mon, Nov 9, 2009 at 4:09 PM, Walter Bright
newshou...@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


Re: Metaprogramming in D : Some Real-world Examples

2009-11-09 Thread Andrei Alexandrescu

Bill Baxter wrote:

On Mon, Nov 9, 2009 at 4:09 PM, Walter Bright
newshou...@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.


Andrei


Re: Metaprogramming in D : Some Real-world Examples

2009-11-09 Thread Nick Sabalausky
Bill Baxter wbax...@gmail.com wrote in message 
news:mailman.290.1257812868.20261.digitalmars-d-annou...@puremagic.com...
 On Mon, Nov 9, 2009 at 4:09 PM, Walter Bright
 newshou...@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 have a few things, mostly part of my SemiTwist D Tools project 
(http://www.dsource.org/projects/semitwist/):

=== Trace / Trace Value ===

Two of my personal favorites (particularly traceVal). Great for debugging.

Implementation and Documentation (search for trace and traceVal, 
implementations are less than 10 lines each):
http://www.dsource.org/projects/semitwist/browser/trunk/src/semitwist/util/mixins.d

Quick Example:
-
mixin(trace!());
mixin(trace!(--EASY TO VISUALLY GREP--));

int myVar=100;
mixin(traceVal!(myVar  ));
mixin(traceVal!(myVar-1));
mixin(traceVal!(min(4,7), max(4,7)));
-

Output:
-
C:\path\file.d(1): trace
--EASY TO VISUALLY GREP--: C:\path\file.d(3): trace
myVar  : 100
myVar-1: 99
min(4,7): 4
max(4,7): 7
-

There's also a traceMixin that can be useful for debugging mixins (it'll 
replace a normal string mixin and echo at compile time via pragma(msg, ) 
the string being mixed in).

=== Init Member ===

Great for DRY in constructors with many initialization parameters.

Implementation and Documentation (at the top of the file):
http://www.dsource.org/projects/semitwist/browser/trunk/src/semitwist/util/mixins.d

Quick Example:
-
mixin(initMember!(someVar));
mixin(initMember!(a, b, c));
-

Turns Into:
-
this.someVar = someVar;
this.a = a;
this.b = b;
this.c = c;
-

Some variations are also available, such as initMemberFrom for copy 
constructors and initFrom copying class members to local vars.

=== Getters ===

DRY mixins for publicly read-only properties, and a lazy version for 
lazily computed  cached read-only properties. A poor replacement for a real 
DRY property syntax, but the next best thing.

Implementation and Documentation (search for getter and getterLazy):
http://www.dsource.org/projects/semitwist/browser/trunk/src/semitwist/util/mixins.d

Quick Example:
-
// Third param optional
mixin(getter!(float, someFloat, 2.5));

mixin(getterLazy!(int, myVar));
private int _myVar_gen()
{
// Ordinarily, this function would be much more complex
// Also, any member func can set _myVar_cached = false;
// to force this to be re-computed on the next request.
return 7;
}
-


Turns Into:
-
private float _someFloat = 2.5;
private float someFloat(float _NEW_VAL_)
{
_someFloat = _NEW_VAL_;
return _someFloat;
}
public float someFloat()
{
return _someFloat;
}

private int _myVar;
private bool _myVar_cached = false;
public int myVar() {
if(!_myVar_cached) {
_myVar_cached = true;
_myVar = _myVar_gen();
}
return _myVar;
}
private int _myVar_gen()
{
// Ordinarily, this function would be much more complex
// Also, any member func can set _myVar_cached = false;
// to force this to be re-computed on the next request.
return 7;
}
-

Variations are also available to use protected (or anything else) instead 
of private.

=== Defer Assert/Ensure ===

Uses metaprogramming to create an alternative to assert() that provides much 
of the usefulness of JUnit-style libs, but without the bulk of wrapping 
things like '==' and '||' in classes/structs or forcing unnatural syntax 
like '(a.equals(b)).or(c.notEquals(d))'. Also reports unexpected exceptions 
and allows requiring a particular exception to be thrown. Implemented in 
less than 200 lines, including blank lines and comments.

Implementation:
http://www.dsource.org/projects/semitwist/browser/trunk/src/semitwist/util/deferAssert.d

Simple Test App:
http://www.dsource.org/projects/semitwist/browser/trunk/src/semitwist/apps/tests/deferAssertTest/main.d

Quick Example:
-
int foo = 2;
mixin(deferAssert!(`foo == 3 || foo  5`, foo is bad));
mixin(deferEnsure!(`foo`, `_ == 3 || _  5`, ensure foo