View mode: basic / threaded / horizontal-split · Log in · Help
November 30, 2005
DMD 0.140: Pure magic!
Not everyone might realise just how revolutionary DMD 0.140 is for 
template metaprogramming.

I submitted this to pragma's DDL "D Dynamic Libraries", used to 
dynamically link to .obj files. In this example, we want to be able to 
call the function
uint add(uint, uint)
which was defined in test.testmodule.obj.
To do this, we need to know the mangled function name, which depends on 
the module name and the types of the parameters. Then we need to do a 
cast to a function pointer of the right type. But the new templates can 
do all the work for us.

THIS LINE:
----------------
auto add = mymodule.load!(uint, "test.testmodule.add", uint, uint)();
----------------
COMPILES TO:
----------------
uint function(uint a,uint b) add = cast(uint function(uint a,uint b)) 
mymodule.LoadExport("_D4test10testmodule3addFkkZk");
----------------
Full name mangling occurs at compile time.

Source available in the DDL forum at www.dsource.org. The code is not 
too obscure (much better than anything at Boost).

It currently only works for fundamental types and pointers. There's not 
enough compile-time or even run-time type info to do function pointers, 
for example. Some compile-time type info would be real nice...

This would be impossible to do in C++. Even to come close would be a 
nightmare.


PS: This code could also be used in the DLL example in the D docs at 
d/dll.html

The code :
-----------------
   alias void function(void*) MyDLL_Initialize_fp;
	FARPROC fp;
	MyDLL_Initialize_fp mydll_initialize;

	HMODULE h = LoadLibraryA("mydll.dll");

	fp = GetProcAddress(h, "D5mydll16MyDLL_InitializeFPvZv");
	if (fp == null)
	{   printf("error loading symbol MyDLL_Initialize()\n");
	    return 1;
	}

	mydll_initialize = cast(MyDLL_Initialize_fp) fp;
	(*mydll_initialize)(std.gc.getGCHandle());
-----------------

can be replaced with:
-------------
      auto mydll = LoadDModule("mydll.dll");
      auto init  = mydll.GetProc!(void, "mydll.MyDLL_Initialize", void 
*)();
      init(std.gc.getGCHandle());
------------
November 30, 2005
Re: DMD 0.140: Pure magic!
he he. I came for a little group snoop, and this is the first post I looked
at, and ...

> This would be impossible to do in C++. Even to come close would be a
> nightmare.

... au contraire, mon ami. Can one pronounce "hubris"? <g>

I've just completed an intial version of just such a library, called
dl_call(), and we're currently having a discussion within the editorial 
panel of "The C++ Source" (http://www.artima.com/cppsource/index.html) on my 
idea of doing a series of articles describing proposing this to the C++ 
standards committee, and the ensuing acceptance/rejection.

(For anyone that's downloaded STLSoft 1.8.9, please ignore the nascent form
of dl_call() in the WinSTL sub-project. The full version is considerably
more full featured. It'll be part of the PlatformSTL sub-project, once I've
ported the code to support UNIX as well as Windows.)


Notwithstanding my slight bubble-pricking above, I don't doubt for a second 
that D's got a lot more welly in it since last I played in anger, and am 
looking forward to playing with it in a big way next year.

Cheers

Matthew
November 30, 2005
Re: DMD 0.140: Pure magic!
Matthew wrote:
> he he. I came for a little group snoop, and this is the first post I looked
> at, and ...
> 
>>This would be impossible to do in C++. Even to come close would be a
>>nightmare.
> 
> ... au contraire, mon ami. Can one pronounce "hubris"? <g>
> 
> I've just completed an intial version of just such a library, called
> dl_call(),

I'm impressed, and rather intrigued - how do you parse a C++ string at 
compile time? And convert the string length to a text integer? I'd 
really like to see the code.

Certainly, it would have been a nightmare for *me* to do it in C++. 
Doing it in D was very straightforward (two nights work).

Hmmm, I'll have to try a bit harder.

and we're currently having a discussion within the editorial
> panel of "The C++ Source" (http://www.artima.com/cppsource/index.html) on my 
> idea of doing a series of articles describing proposing this to the C++ 
> standards committee, and the ensuing acceptance/rejection.

I'll look out for that.
> 
> Notwithstanding my slight bubble-pricking above, I don't doubt for a second 
> that D's got a lot more welly in it since last I played in anger, and am 
> looking forward to playing with it in a big way next year.

Definitely. I look forward to seeing the results, too.
November 30, 2005
Re: DMD 0.140: Pure magic!
Don Clugston wrote:
> Not everyone might realise just how revolutionary DMD 0.140 is for 
> template metaprogramming.
> 
> I submitted this to pragma's DDL "D Dynamic Libraries", used to 
> dynamically link to .obj files. In this example, we want to be able to 
> call the function
> uint add(uint, uint)
> which was defined in test.testmodule.obj.
> To do this, we need to know the mangled function name, which depends on 
> the module name and the types of the parameters. Then we need to do a 
> cast to a function pointer of the right type. But the new templates can 
> do all the work for us.
> 
> THIS LINE:
> ----------------
> auto add = mymodule.load!(uint, "test.testmodule.add", uint, uint)();
> ----------------
> COMPILES TO:
> ----------------
> uint function(uint a,uint b) add = cast(uint function(uint a,uint b)) 
> mymodule.LoadExport("_D4test10testmodule3addFkkZk");
> ----------------
> Full name mangling occurs at compile time.
> 
> Source available in the DDL forum at www.dsource.org. The code is not 
> too obscure (much better than anything at Boost).

Not too obsure? The code is looking great and very understandable.

> 
> It currently only works for fundamental types and pointers. There's not 
> enough compile-time or even run-time type info to do function pointers, 
> for example. Some compile-time type info would be real nice...
> 
> This would be impossible to do in C++. Even to come close would be a 
> nightmare.
> 
> 
> PS: This code could also be used in the DLL example in the D docs at 
> d/dll.html
> 

...
November 30, 2005
Re: DMD 0.140: Pure magic!
In article <dmke9m$ott$1@digitaldaemon.com>, Don Clugston says...
>
>Matthew wrote:
>> he he. I came for a little group snoop, and this is the first post I looked
>> at, and ...
>> 
>>>This would be impossible to do in C++. Even to come close would be a
>>>nightmare.
>> 
>> ... au contraire, mon ami. Can one pronounce "hubris"? <g>
>> 
>> I've just completed an intial version of just such a library, called
>> dl_call(),
>
>I'm impressed, and rather intrigued - how do you parse a C++ string at 
>compile time? And convert the string length to a text integer? I'd 
>really like to see the code.
>
>Certainly, it would have been a nightmare for *me* to do it in C++. 
>Doing it in D was very straightforward (two nights work).
>
>Hmmm, I'll have to try a bit harder.

Don, here's something I've given some thought: are you familiar with XSLT/XPATH
2.0?

As XSL is a *template* language, it is most directly supported by the support
that XPATH brings to the table.  The 2.0 specification, especially for strings,
is the bare-minimum needed to do nearly any kind of parsing or processing one
could imagine (although some productions take some serious coding to work).

http://www.w3schools.com/xpath/xpath_functions.asp#string

Maybe the string portion of the spec (described at URL above) might point you in
the right direction for a more comprehensive/complete compile-time facility.  I
think slicing already covers most of these, leaving case-switching,
search-and-replace, and the like; I think these all boil down into combinations
of compare-and-slice and concat.  

Some kind of easy iteration (recursive template that takes args like for-each)
would be a huge plus too.

The really, really hard part?  The second argument to tokenize() is a
regular-expression.  Teach D how to do that at compile-time, and there's not
much left.


- EricAnderton at yahoo
November 30, 2005
Re: DMD 0.140: Pure magic!
Don Clugston wrote:
> Matthew wrote:
>> he he. I came for a little group snoop, and this is the first post I 
>> looked
>> at, and ...
>>
>>> This would be impossible to do in C++. Even to come close would be a
>>> nightmare.
>>
>> ... au contraire, mon ami. Can one pronounce "hubris"? <g>
>>
>> I've just completed an intial version of just such a library, called
>> dl_call(),
> 
> I'm impressed, and rather intrigued - how do you parse a C++ string at 
> compile time? And convert the string length to a text integer? I'd 
> really like to see the code.

Same here.  I think it would be possible to cobble something bearable 
together using a combination of macro and template language, but the 
result would look a lot more like input for Spirit than pure string 
manipulation.  The real nasty part here is that I don't think there's 
any way to split strings at compile-time in C++, so everything would 
likely have to be assembled from common substrings (perhaps even one per 
letter).


Sean
December 01, 2005
Re: DMD 0.140: Pure magic!
"Don Clugston" <dac@nospam.com.au> wrote in message
news:dmk465$fq3$1@digitaldaemon.com...
> THIS LINE:
> ----------------
> auto add = mymodule.load!(uint, "test.testmodule.add", uint, uint)();
> ----------------
> COMPILES TO:
> ----------------
> uint function(uint a,uint b) add = cast(uint function(uint a,uint b))
> mymodule.LoadExport("_D4test10testmodule3addFkkZk");
> ----------------
> Full name mangling occurs at compile time.

This is pretty incredible. I had no idea this could be done <g>.

> It currently only works for fundamental types and pointers. There's not
> enough compile-time or even run-time type info to do function pointers,
> for example. Some compile-time type info would be real nice...

What's missing from function pointers? Note that the name demangler
(std.demangle) can demangle function pointers, so the information must be
complete.
December 01, 2005
Re: DMD 0.140: Pure magic!
"Matthew" <matthew@stlsoft.com> wrote in message
news:dmk89b$jhi$1@digitaldaemon.com...
> > This would be impossible to do in C++. Even to come close would be a
> > nightmare.
>
> ... au contraire, mon ami. Can one pronounce "hubris"? <g>
>
> I've just completed an intial version of just such a library, called
> dl_call(), and we're currently having a discussion within the editorial
> panel of "The C++ Source" (http://www.artima.com/cppsource/index.html) on
my
> idea of doing a series of articles describing proposing this to the C++
> standards committee, and the ensuing acceptance/rejection.

A comparitive review would be fun. Want to go for it?
December 01, 2005
Re: DMD 0.140: Pure magic!
Walter Bright wrote:
> "Don Clugston" <dac@nospam.com.au> wrote in message
> news:dmk465$fq3$1@digitaldaemon.com...
> 
>>THIS LINE:
>>----------------
>>auto add = mymodule.load!(uint, "test.testmodule.add", uint, uint)();
>>----------------
>>COMPILES TO:
>>----------------
>>uint function(uint a,uint b) add = cast(uint function(uint a,uint b))
>>mymodule.LoadExport("_D4test10testmodule3addFkkZk");
>>----------------
>>Full name mangling occurs at compile time.
> 
> This is pretty incredible. I had no idea this could be done <g>.

And it's not even ugly. That's a very primitive use of template string 
value parameters. Despite Matthew's comment, I do think we're crossing 
into unexplored territory.

>>It currently only works for fundamental types and pointers. There's not
>>enough compile-time or even run-time type info to do function pointers,
>>for example. Some compile-time type info would be real nice...
> 
> What's missing from function pointers? Note that the name demangler
> (std.demangle) can demangle function pointers, so the information must be
> complete.

All the mangling information is present in a mangled string, but I don't 
know any way to find out what the function arguments are.
Suppose T is a function pointer type.

R function (P1, P2, P3)

What are R, P1, P2, P3 ? You can work out what R is, using
is(T R : function)
which gives you the type of the return value.
In C++, you can find out what P1, P2, P3 are, by using implicit template 
instantiation. But in D, I don't even know how I can work out how many 
parameters there are. (Maybe there is, and I've just missed it).

Even the runtime typeinfo structure seems to be incomplete.
Example:

writefln(typeid(int *), "  ", typeid(int function(char *, creal)));

prints:
int *    int()*

yet from std.demangle, it looks as though even inout vs out parameters 
are distinguished in the mangled name.

Musing...

Now, a simple-to-implement way of doing this, and ensuring that all 
presnt and future types are covered, would be to include a 
__mangletypeof() function or property, valid for any type, which 
converts a type to a const char[], using exactly the same mangling 
algorithm which is used by the linker for individual types.
So that std.demangle(__mangletypeof(int)) would return "int".

Note: if there was some kind of __demangletypeof() as well, we would 
have well-supported typelists by the backdoor -- mangle the types, 
perform string manipulations on them, and demangle when you're done. But 
perhaps this is all far, far too much rope...

Could also be done from a library, if we had implicit function template 
instantiation. But I'm guessing that's not coming any time soon.
December 01, 2005
Re: DMD 0.140: Pure magic!
In article <dmmhfc$2m8p$1@digitaldaemon.com>, Don Clugston says...
>
>Walter Bright wrote:
>> "Don Clugston" <dac@nospam.com.au> wrote in message
>> news:dmk465$fq3$1@digitaldaemon.com...
>> 
>>>THIS LINE:
>>>----------------
>>>auto add = mymodule.load!(uint, "test.testmodule.add", uint, uint)();
>>>----------------
>>>COMPILES TO:
>>>----------------
>>>uint function(uint a,uint b) add = cast(uint function(uint a,uint b))
>>>mymodule.LoadExport("_D4test10testmodule3addFkkZk");
>>>----------------
>>>Full name mangling occurs at compile time.
>> 
>> This is pretty incredible. I had no idea this could be done <g>.
>
>And it's not even ugly. That's a very primitive use of template string 
>value parameters. Despite Matthew's comment, I do think we're crossing 
>into unexplored territory.
>
>>>It currently only works for fundamental types and pointers. There's not
>>>enough compile-time or even run-time type info to do function pointers,
>>>for example. Some compile-time type info would be real nice...
>> 
>> What's missing from function pointers? Note that the name demangler
>> (std.demangle) can demangle function pointers, so the information must be
>> complete.
>
>All the mangling information is present in a mangled string, but I don't 
>know any way to find out what the function arguments are.
>Suppose T is a function pointer type.
>
>R function (P1, P2, P3)
>
>What are R, P1, P2, P3 ? You can work out what R is, using
>is(T R : function)
>which gives you the type of the return value.
>In C++, you can find out what P1, P2, P3 are, by using implicit template 
>instantiation. But in D, I don't even know how I can work out how many 
>parameters there are. (Maybe there is, and I've just missed it).
>
>Even the runtime typeinfo structure seems to be incomplete.
>Example:
>
>writefln(typeid(int *), "  ", typeid(int function(char *, creal)));
>
>prints:
>int *    int()*
>
>yet from std.demangle, it looks as though even inout vs out parameters 
>are distinguished in the mangled name.
>
>Musing...
>
>Now, a simple-to-implement way of doing this, and ensuring that all 
>presnt and future types are covered, would be to include a 
>__mangletypeof() function or property, valid for any type, which 
>converts a type to a const char[], using exactly the same mangling 
>algorithm which is used by the linker for individual types.
>So that std.demangle(__mangletypeof(int)) would return "int".
>
>Note: if there was some kind of __demangletypeof() as well, we would 
>have well-supported typelists by the backdoor -- mangle the types, 
>perform string manipulations on them, and demangle when you're done. But 
>perhaps this is all far, far too much rope...
>
>Could also be done from a library, if we had implicit function template 
>instantiation. But I'm guessing that's not coming any time soon.
>

Yes, I feel like walter gave me a christmas present. Ive been wanting this from
c++ for ages. We have something pretty awesome here. As far as Im concerned
anyone whos not using D is missing out...
« First   ‹ Prev
1 2 3
Top | Discussion index | About this forum | D home