Jump to page: 1 28  
Page
Thread overview
Meta-programming supported in the language
May 05, 2005
Bill Baxter
May 05, 2005
Kevin Bealer
May 05, 2005
Kevin Bealer
May 05, 2005
Andrew Fedoniouk
May 05, 2005
Bill Baxter
May 05, 2005
Andrew Fedoniouk
May 05, 2005
Bill Baxter
May 05, 2005
Vladimir
May 05, 2005
Mike Capp
May 05, 2005
Bill Baxter
May 05, 2005
Mike Capp
May 06, 2005
Kevin Bealer
May 07, 2005
Bill Baxter
May 06, 2005
Bill Baxter
May 05, 2005
Lionello Lunesu
May 05, 2005
Bill Baxter
May 06, 2005
Lionello Lunesu
May 06, 2005
Derek Parnell
May 06, 2005
Lionello Lunesu
May 07, 2005
Bill Baxter
May 07, 2005
Bill Baxter
May 05, 2005
Bill Baxter
May 05, 2005
Benji Smith
May 06, 2005
Bill Baxter
May 06, 2005
Derek Parnell
May 06, 2005
Bill Baxter
May 06, 2005
Derek Parnell
Re: Build (was Meta-programming supported in the language)
May 06, 2005
Bill Baxter
May 07, 2005
Bill Baxter
May 09, 2005
Benji Smith
May 06, 2005
Kevin Bealer
May 08, 2005
Walter
May 08, 2005
Bill Baxter
May 09, 2005
Sean Kelly
May 13, 2005
Walter
May 13, 2005
Sean Kelly
May 13, 2005
Thomas Kuehne
May 13, 2005
Walter
May 15, 2005
Kevin Bealer
May 15, 2005
Kevin Bealer
May 15, 2005
Sean Kelly
May 17, 2005
Walter
May 15, 2005
Walter
May 13, 2005
Walter
May 13, 2005
Sean Kelly
May 16, 2005
TechnoZeus
May 17, 2005
Walter
May 17, 2005
TechnoZeus
May 13, 2005
Matthias Spycher
May 14, 2005
Dave
May 15, 2005
Walter
May 14, 2005
Vladimir
May 14, 2005
Matthias Becker
May 16, 2005
TechnoZeus
May 14, 2005
Burton Radons
May 14, 2005
Walter
May 14, 2005
Burton Radons
May 15, 2005
Walter
May 15, 2005
Burton Radons
May 15, 2005
Dave
May 16, 2005
TechnoZeus
May 18, 2005
Brian White
May 19, 2005
TechnoZeus
May 15, 2005
Vathix
May 16, 2005
Walter
May 19, 2005
Eugene Pelekhay
May 19, 2005
TechnoZeus
May 23, 2005
Walter
[thanks Walter] Re: Meta-programming supported in the language
May 24, 2005
TechnoZeus
May 20, 2005
Matthias Spycher
May 16, 2005
TechnoZeus
May 16, 2005
Bill Baxter
May 16, 2005
Walter
May 16, 2005
p9e883002
May 16, 2005
Walter
May 17, 2005
p9e883002
May 17, 2005
Walter
Jun 10, 2005
Georg Wrede
May 05, 2005
Howdy again D folks.
This is my second message on what I think could be improved about C++, and what
I'm hoping D either already supports, or could in the future (although for this
one I'm pretty sure D doesn't have this currently).

This comment is about template metaprogramming and metaprogramming in general. It's a little more pie-in-the-sky than my last comment.

Projects like Blitz++ and Boost in the C++ world have proven that metaprogramming techniques can be very useful.  The general idea is to be able to do some general purpose computation on types or constants but to have it run at compile time rather than run time.  The C++ template mechanism, it turns out, can be made to do this.  Popular parlor tricks include things like making your templates compute integer factorials at compile time, but there are plenty of more useful things to do with it too. :-)   Anyway, I presume many folks are familiar with the idea.  If not, google for "template metaprogramming".  Gobs of hits.

The problem is that the C++ template mechanism just wasn't designed as a general purpose compile-time computing language.  It's the same old C vs C++ argument all over again.  Yes you _can_ write programs that are object oriented in C, but C just doesn't do much to help you.  It doesn't facilitate the paradigm. Similarly you _can_ do metaprogramming with C++ templates, but the results are probably the least readable, least maintainable gobbledy-gook I've ever had the misfortune to see.

What's needed is actual language support for the paradigm.  I'm not sure what that would look like, but a fresh C++-like language such as D seems have great potential for offering such a solution.  Basically the idea is you'd be able to write code to execute at compile time that looks more or less like regular code, but in which types are first class values and can be passed around and returned, etc.

Here's one really simple example of one common use of metaprogramming to give a
feel for what I'm talking about.  The idea is you want to be able to say
something like integer<24> to get the smallest native integral type that can
hold 24 bits.  A C++ template metaprogramming solution can be seen here:
http://www.eptacom.net/pubblicazioni/pub_eng/paramint.html
(Scroll down to the bottom to see two different versions of the code).

Yikes!  All that is, really, is just an if-else, but dressed up in C++ template metaprogramming it takes about a page of code!  My thought is that if the language actually had first-class support for metaprogramming, then you could just do something like write a short metafunction that returns a type:

metafun type integer(int numbits)
{
if (numbits<=sizeof(char)) return char;
if (numbits<=sizeof(short)) return short;
if (numbits<=sizeof(int)) return int;
if (numbits<=sizeof(long)) return long;
if (numbits<=sizeof(cent)) return cent;

metathrow "Compiler error";
}

Or something like that.  The logic and intent of the above code is infinitely more clear to the reader than the C++ metaprogramming code linked to above.

Obviously there are tons of issues to be worked out with making something like this work (syntax, what meta types are needed, compile-time error handling, etc), but it just seems to me that the past 7 or 8 years or so of work on C++ template metaprogramming has proven that this stuff is useful, but it has also proven that to do anything useful with it you have to write pages of "write-only" code.  This stuff is so ugly that it sends people running to perl! :-P  Yes, it's that bad, folks. :-)

Thoughts?  Any chances something like this could ever come to D?

Bill Baxter


May 05, 2005
In article <d5c1mu$640$1@digitaldaemon.com>, Bill Baxter says...
>
>Howdy again D folks.
>This is my second message on what I think could be improved about C++, and what
>I'm hoping D either already supports, or could in the future (although for this
>one I'm pretty sure D doesn't have this currently).
>
>This comment is about template metaprogramming and metaprogramming in general. It's a little more pie-in-the-sky than my last comment.
>
>Projects like Blitz++ and Boost in the C++ world have proven that metaprogramming techniques can be very useful.  The general idea is to be able to do some general purpose computation on types or constants but to have it run at compile time rather than run time.  The C++ template mechanism, it turns out, can be made to do this.  Popular parlor tricks include things like making your templates compute integer factorials at compile time, but there are plenty of more useful things to do with it too. :-)   Anyway, I presume many folks are familiar with the idea.  If not, google for "template metaprogramming".  Gobs of hits.
>
>The problem is that the C++ template mechanism just wasn't designed as a general purpose compile-time computing language.  It's the same old C vs C++ argument all over again.  Yes you _can_ write programs that are object oriented in C, but C just doesn't do much to help you.  It doesn't facilitate the paradigm. Similarly you _can_ do metaprogramming with C++ templates, but the results are probably the least readable, least maintainable gobbledy-gook I've ever had the misfortune to see.
>
>What's needed is actual language support for the paradigm.  I'm not sure what that would look like, but a fresh C++-like language such as D seems have great potential for offering such a solution.  Basically the idea is you'd be able to write code to execute at compile time that looks more or less like regular code, but in which types are first class values and can be passed around and returned, etc.
>
>Here's one really simple example of one common use of metaprogramming to give a
>feel for what I'm talking about.  The idea is you want to be able to say
>something like integer<24> to get the smallest native integral type that can
>hold 24 bits.  A C++ template metaprogramming solution can be seen here:
>http://www.eptacom.net/pubblicazioni/pub_eng/paramint.html
>(Scroll down to the bottom to see two different versions of the code).
>
>Yikes!  All that is, really, is just an if-else, but dressed up in C++ template metaprogramming it takes about a page of code!  My thought is that if the language actually had first-class support for metaprogramming, then you could just do something like write a short metafunction that returns a type:
>
>metafun type integer(int numbits)
>{
>if (numbits<=sizeof(char)) return char;
>if (numbits<=sizeof(short)) return short;
>if (numbits<=sizeof(int)) return int;
>if (numbits<=sizeof(long)) return long;
>if (numbits<=sizeof(cent)) return cent;
>
>metathrow "Compiler error";
>}
>
>Or something like that.  The logic and intent of the above code is infinitely more clear to the reader than the C++ metaprogramming code linked to above.
>
>Obviously there are tons of issues to be worked out with making something like this work (syntax, what meta types are needed, compile-time error handling, etc), but it just seems to me that the past 7 or 8 years or so of work on C++ template metaprogramming has proven that this stuff is useful, but it has also proven that to do anything useful with it you have to write pages of "write-only" code.  This stuff is so ugly that it sends people running to perl! :-P  Yes, it's that bad, folks. :-)
>
>Thoughts?  Any chances something like this could ever come to D?
>
>Bill Baxter

This has been discussed, a little, on here before.  I think Walter said he's had email discussions and sees some promise in this direction or thereabouts, but I'm not positive.


But meta-programming is something that all modern optimizing compilers do to a *degree*.  They do it whenever you write code that can be unrolled and precomputed.

:int foo() {
:  int x = 5;
:  for(int j = 0; j<10; j++) {
:    x = x + j;
:  }
:  return x;
:}

This could be a compiled loop.... Or, the compiler can unroll the loop and do ALL of it at compile time.

What if there was a "version-like" statement that asked the compiler to do this? You could do something like:

: compileTime {
:   char[] x = "abcd";
:   int abcd_hash = x[0] + x[1] + x[2] + x[3];
: }

This would be something like the "inline" statement in C++.  Can the compiler really fold that string into an integer?  Will it?

The compileTime{} pragma would essentially say "do this at compile time, or issue a warning if you can't".

This solves the factorial problem:

int factorial(int i) { /whatever/ };

compileTime {
int x = factorial();
}

compileTime{} would mean the compiler is expected to unroll loops, inline every function, and basically run the code at compile time.  If the above "string" example did not work (ie it used a user-provided string), then the compileTime statement fails with an error or warning.

If reflection is added to the D language, then you could provide the ability to iterate over methods and fields, or build classes.  Combine reflection and compileTime, and you can do template meta tasks.

Kevin



May 05, 2005
In article <d5c8s4$d82$1@digitaldaemon.com>, Kevin Bealer says... ..
>
>If reflection is added to the D language, then you could provide the ability to iterate over methods and fields, or build classes.  Combine reflection and compileTime, and you can do template meta tasks.

To clarify... What I meant was, you could solve problems in the template meta-programming domain, but use natural "D" syntax to code it up.

It would be a hint, like inline, but more powerful, pointing the compiler to places where it could "optimize completely".

Computing calculated constants and unrolling loops is a small step on the road to the full "programming at compile time" goal.

A more powerful step down the road is the ability to edit classes at compile time.  Mark a bunch of classes as inheriting from "serializable" and write some generic pickling code for primitives.  Then the "serializable" base class needs the ability to iterate over the fields of its subclasses.  Instant XML from D structs.

(I want the power to write programs that write the rest of themself.  A little more juice, just a little more and I'll be happy...)

Kevin



May 05, 2005
Right on, Kevin.  One thing to keep in mind, though, when you talk about giving these "compileTime{}" blocks "all the power of D", is that D is designed to be an efficient, statically-typed, *compiled* language, and to achieve that it has to sacrifice some of the niceties of more dynamic typing to achieve the desired performance.  I personally think a compile-time language should be as dynamic as possible.  It effectivly is going to be an interpreted rather than compiled thing anyway, so why not make it as dynamic as possible?  Like you said, the dream is basically to write metacode that can use introspection on classes at compile time to algorithmically generate types, classes, and the code that eventually gets compiled.  If I were going to write an external code generator, I'd definitely use a scripting language, so why not give the same degree of flexibility to the built-in meta-language?  And give it good text manipulation operators too, search, replace, munge, regex etc.  Just like you'd expect in a scripting language.

One issue, however, is that that doesn't really mesh well with the concept you have of "falling back" to run-time computation if the compiler determines it can't do it at compile time.  Though, I don't know if that's such a great idea, really.  I don't know why for sure, but my gut tells me that compile-time execution and run-time execution aren't quite as similar as inline and non-inline are to each other and that's going to cause problems.  For one thing, whereas it's always possible to just not inline something, it won't always be possible to not run some code at compile-time, say if the return value of the code is in fact a type rather than a number.  If you're working with types as data, then you absolutely can't run the code at runtime.

From a aethetics point of view, though, I do agree that it would be nice if the meta-language were as similar to the D language as possible.  It would definitely be nice if it were easy to convert "compile-time" code to run-time code where the conversion made sense.  But still I don't want to give up the flexibility of a more dynamically-typed language.

I think something like this would also really once and for all make macros obsolete.  I've heard various gurus saying that the combination of inline functions, typedefs, templates, and const variables makes macros obsolete, but there's one more case where people have historically used macros that the gurus seem to have been forgotten about: language extensions.  Anyone ever seen how you make a usable object system that works in C? Answer: lots of macros.  Anyone taken a look at the "Aspect Oriented Programming" extensions for C++?  Any guess as to how they implement it?  Yep. Bunch o' Macros (among other things).  Ever heard about the trick for making the broken for loop scope in MSVC6 work properly? Macros again.  Unfortunately macros are pretty indiscriminate in how the go and muck things up and the lack of scoping etc causes real messes.  Maybe it's possible make all those sorts of language extension types of things possible but in a cleaner way.

I'm just thinking out loud here, but it's definitely all related.  Templates, metaprogramming, code generation, macros.  Wouldn't it be cool to have it all unified and done right?

Just a small matter of figuring out what "done right" means. :-)  Unfortunately I'm just an armchair compiler writer.  :-)

Oh, one final thing to throw into the mix -- special tag keywords. Things like 'synchronized' that change some aspect of how a method runs.  Or Qt's "signal" and "slot" keywords.  Qt runs a lex/yacc parser ('moc') on header files to handle those keywords and generate boilerplate code to implement them.  Wouldn't it be nice if the language supported the ability for users to add such tags? Another one that would be nice to have is "script", i.e. generate wrapper code for binding this method with a scripting language.  Boost.python for instance lets you put code _elsewhere_ that says generate wrapper code for this method, but sometimes it would be nice if you could just flag the method itself right there where you declare it.

--bb

In article <d5c8s4$d82$1@digitaldaemon.com>, Kevin Bealer says...
>
>In article <d5c1mu$640$1@digitaldaemon.com>, Bill Baxter says...
>>
>>Howdy again D folks.
>>This is my second message on what I think could be improved about C++, and what
>>I'm hoping D either already supports, or could in the future (although for this
>>one I'm pretty sure D doesn't have this currently).
>>
>>This comment is about template metaprogramming and metaprogramming in general. It's a little more pie-in-the-sky than my last comment.
>>
>>Projects like Blitz++ and Boost in the C++ world have proven that metaprogramming techniques can be very useful.  The general idea is to be able to do some general purpose computation on types or constants but to have it run at compile time rather than run time.  The C++ template mechanism, it turns out, can be made to do this.  Popular parlor tricks include things like making your templates compute integer factorials at compile time, but there are plenty of more useful things to do with it too. :-)   Anyway, I presume many folks are familiar with the idea.  If not, google for "template metaprogramming".  Gobs of hits.
>>
>>The problem is that the C++ template mechanism just wasn't designed as a general purpose compile-time computing language.  It's the same old C vs C++ argument all over again.  Yes you _can_ write programs that are object oriented in C, but C just doesn't do much to help you.  It doesn't facilitate the paradigm. Similarly you _can_ do metaprogramming with C++ templates, but the results are probably the least readable, least maintainable gobbledy-gook I've ever had the misfortune to see.
>>
>>What's needed is actual language support for the paradigm.  I'm not sure what that would look like, but a fresh C++-like language such as D seems have great potential for offering such a solution.  Basically the idea is you'd be able to write code to execute at compile time that looks more or less like regular code, but in which types are first class values and can be passed around and returned, etc.
>>
>>Here's one really simple example of one common use of metaprogramming to give a
>>feel for what I'm talking about.  The idea is you want to be able to say
>>something like integer<24> to get the smallest native integral type that can
>>hold 24 bits.  A C++ template metaprogramming solution can be seen here:
>>http://www.eptacom.net/pubblicazioni/pub_eng/paramint.html
>>(Scroll down to the bottom to see two different versions of the code).
>>
>>Yikes!  All that is, really, is just an if-else, but dressed up in C++ template metaprogramming it takes about a page of code!  My thought is that if the language actually had first-class support for metaprogramming, then you could just do something like write a short metafunction that returns a type:
>>
>>metafun type integer(int numbits)
>>{
>>if (numbits<=sizeof(char)) return char;
>>if (numbits<=sizeof(short)) return short;
>>if (numbits<=sizeof(int)) return int;
>>if (numbits<=sizeof(long)) return long;
>>if (numbits<=sizeof(cent)) return cent;
>>
>>metathrow "Compiler error";
>>}
>>
>>Or something like that.  The logic and intent of the above code is infinitely more clear to the reader than the C++ metaprogramming code linked to above.
>>
>>Obviously there are tons of issues to be worked out with making something like this work (syntax, what meta types are needed, compile-time error handling, etc), but it just seems to me that the past 7 or 8 years or so of work on C++ template metaprogramming has proven that this stuff is useful, but it has also proven that to do anything useful with it you have to write pages of "write-only" code.  This stuff is so ugly that it sends people running to perl! :-P  Yes, it's that bad, folks. :-)
>>
>>Thoughts?  Any chances something like this could ever come to D?
>>
>>Bill Baxter
>
>This has been discussed, a little, on here before.  I think Walter said he's had email discussions and sees some promise in this direction or thereabouts, but I'm not positive.
>
>
>But meta-programming is something that all modern optimizing compilers do to a *degree*.  They do it whenever you write code that can be unrolled and precomputed.
>
>:int foo() {
>:  int x = 5;
>:  for(int j = 0; j<10; j++) {
>:    x = x + j;
>:  }
>:  return x;
>:}
>
>This could be a compiled loop.... Or, the compiler can unroll the loop and do ALL of it at compile time.
>
>What if there was a "version-like" statement that asked the compiler to do this? You could do something like:
>
>: compileTime {
>:   char[] x = "abcd";
>:   int abcd_hash = x[0] + x[1] + x[2] + x[3];
>: }
>
>This would be something like the "inline" statement in C++.  Can the compiler really fold that string into an integer?  Will it?
>
>The compileTime{} pragma would essentially say "do this at compile time, or issue a warning if you can't".
>
>This solves the factorial problem:
>
>int factorial(int i) { /whatever/ };
>
>compileTime {
>int x = factorial();
>}
>
>compileTime{} would mean the compiler is expected to unroll loops, inline every function, and basically run the code at compile time.  If the above "string" example did not work (ie it used a user-provided string), then the compileTime statement fails with an error or warning.
>
>If reflection is added to the D language, then you could provide the ability to iterate over methods and fields, or build classes.  Combine reflection and compileTime, and you can do template meta tasks.
>
>Kevin
>
>
>


May 05, 2005
> (I want the power to write programs that write the rest of themself.  A
> little
> more juice, just a little more and I'll be happy...)

Ummm...

I would rather want to have a debugger which has a power to debug programs that write the rest of themselves :)

Btw: what is the problem now to write such programs?
Derek did it, name is Build.exe.

Huh?


May 05, 2005
Hi, Bill,

(not so) Wild idea  : to put your sources under httpd and config it for use lets say PHP processing on D files.

So
>>compileTime {
>>int x = factorial();
>>}

will be just a

int x = <% factorial(N) %>;

This is reliable and can be used now.
You even can assemble such preprocessor
in D using DMDScript for example.

Huh?
I like my own idea :) The ultimate preprocessor.
The way better as it clearly separates compile/runtime namespaces.
And you can debug your meta and programs separately.
And finally close this metaprogramming theme for now and beyond.

Andrew.




"Bill Baxter" <Bill_member@pathlink.com> wrote in message news:d5cf7e$hh1$1@digitaldaemon.com...
> Right on, Kevin.  One thing to keep in mind, though, when you talk about
> giving
> these "compileTime{}" blocks "all the power of D", is that D is designed
> to be
> an efficient, statically-typed, *compiled* language, and to achieve that
> it has
> to sacrifice some of the niceties of more dynamic typing to achieve the
> desired
> performance.  I personally think a compile-time language should be as
> dynamic as
> possible.  It effectivly is going to be an interpreted rather than
> compiled
> thing anyway, so why not make it as dynamic as possible?  Like you said,
> the
> dream is basically to write metacode that can use introspection on classes
> at
> compile time to algorithmically generate types, classes, and the code that
> eventually gets compiled.  If I were going to write an external code
> generator,
> I'd definitely use a scripting language, so why not give the same degree
> of
> flexibility to the built-in meta-language?  And give it good text
> manipulation
> operators too, search, replace, munge, regex etc.  Just like you'd expect
> in a
> scripting language.
>
> One issue, however, is that that doesn't really mesh well with the concept
> you
> have of "falling back" to run-time computation if the compiler determines
> it
> can't do it at compile time.  Though, I don't know if that's such a great
> idea,
> really.  I don't know why for sure, but my gut tells me that compile-time
> execution and run-time execution aren't quite as similar as inline and
> non-inline are to each other and that's going to cause problems.  For one
> thing,
> whereas it's always possible to just not inline something, it won't always
> be
> possible to not run some code at compile-time, say if the return value of
> the
> code is in fact a type rather than a number.  If you're working with types
> as
> data, then you absolutely can't run the code at runtime.
>
> From a aethetics point of view, though, I do agree that it would be nice
> if the
> meta-language were as similar to the D language as possible.  It would
> definitely be nice if it were easy to convert "compile-time" code to
> run-time
> code where the conversion made sense.  But still I don't want to give up
> the
> flexibility of a more dynamically-typed language.
>
> I think something like this would also really once and for all make macros
> obsolete.  I've heard various gurus saying that the combination of inline
> functions, typedefs, templates, and const variables makes macros obsolete,
> but
> there's one more case where people have historically used macros that the
> gurus
> seem to have been forgotten about: language extensions.  Anyone ever seen
> how
> you make a usable object system that works in C? Answer: lots of macros.
> Anyone
> taken a look at the "Aspect Oriented Programming" extensions for C++?  Any
> guess
> as to how they implement it?  Yep. Bunch o' Macros (among other things).
> Ever
> heard about the trick for making the broken for loop scope in MSVC6 work
> properly? Macros again.  Unfortunately macros are pretty indiscriminate in
> how
> the go and muck things up and the lack of scoping etc causes real messes.
> Maybe
> it's possible make all those sorts of language extension types of things
> possible but in a cleaner way.
>
> I'm just thinking out loud here, but it's definitely all related.
> Templates,
> metaprogramming, code generation, macros.  Wouldn't it be cool to have it
> all
> unified and done right?
>
> Just a small matter of figuring out what "done right" means. :-)
> Unfortunately
> I'm just an armchair compiler writer.  :-)
>
> Oh, one final thing to throw into the mix -- special tag keywords. Things
> like
> 'synchronized' that change some aspect of how a method runs.  Or Qt's
> "signal"
> and "slot" keywords.  Qt runs a lex/yacc parser ('moc') on header files to
> handle those keywords and generate boilerplate code to implement them.
> Wouldn't
> it be nice if the language supported the ability for users to add such
> tags?
> Another one that would be nice to have is "script", i.e. generate wrapper
> code
> for binding this method with a scripting language.  Boost.python for
> instance
> lets you put code _elsewhere_ that says generate wrapper code for this
> method,
> but sometimes it would be nice if you could just flag the method itself
> right
> there where you declare it.
>
> --bb
>
> In article <d5c8s4$d82$1@digitaldaemon.com>, Kevin Bealer says...
>>
>>In article <d5c1mu$640$1@digitaldaemon.com>, Bill Baxter says...
>>>
>>>Howdy again D folks.
>>>This is my second message on what I think could be improved about C++,
>>>and what
>>>I'm hoping D either already supports, or could in the future (although
>>>for this
>>>one I'm pretty sure D doesn't have this currently).
>>>
>>>This comment is about template metaprogramming and metaprogramming in
>>>general.
>>>It's a little more pie-in-the-sky than my last comment.
>>>
>>>Projects like Blitz++ and Boost in the C++ world have proven that
>>>metaprogramming techniques can be very useful.  The general idea is to be
>>>able
>>>to do some general purpose computation on types or constants but to have
>>>it run
>>>at compile time rather than run time.  The C++ template mechanism, it
>>>turns out,
>>>can be made to do this.  Popular parlor tricks include things like making
>>>your
>>>templates compute integer factorials at compile time, but there are
>>>plenty of
>>>more useful things to do with it too. :-)   Anyway, I presume many folks
>>>are
>>>familiar with the idea.  If not, google for "template metaprogramming".
>>>Gobs of
>>>hits.
>>>
>>>The problem is that the C++ template mechanism just wasn't designed as a
>>>general
>>>purpose compile-time computing language.  It's the same old C vs C++
>>>argument
>>>all over again.  Yes you _can_ write programs that are object oriented in
>>>C, but
>>>C just doesn't do much to help you.  It doesn't facilitate the paradigm.
>>>Similarly you _can_ do metaprogramming with C++ templates, but the
>>>results are
>>>probably the least readable, least maintainable gobbledy-gook I've ever
>>>had the
>>>misfortune to see.
>>>
>>>What's needed is actual language support for the paradigm.  I'm not sure
>>>what
>>>that would look like, but a fresh C++-like language such as D seems have
>>>great
>>>potential for offering such a solution.  Basically the idea is you'd be
>>>able to
>>>write code to execute at compile time that looks more or less like
>>>regular code,
>>>but in which types are first class values and can be passed around and
>>>returned,
>>>etc.
>>>
>>>Here's one really simple example of one common use of metaprogramming to
>>>give a
>>>feel for what I'm talking about.  The idea is you want to be able to say
>>>something like integer<24> to get the smallest native integral type that
>>>can
>>>hold 24 bits.  A C++ template metaprogramming solution can be seen here:
>>>http://www.eptacom.net/pubblicazioni/pub_eng/paramint.html
>>>(Scroll down to the bottom to see two different versions of the code).
>>>
>>>Yikes!  All that is, really, is just an if-else, but dressed up in C++
>>>template
>>>metaprogramming it takes about a page of code!  My thought is that if the
>>>language actually had first-class support for metaprogramming, then you
>>>could
>>>just do something like write a short metafunction that returns a type:
>>>
>>>metafun type integer(int numbits)
>>>{
>>>if (numbits<=sizeof(char)) return char;
>>>if (numbits<=sizeof(short)) return short;
>>>if (numbits<=sizeof(int)) return int;
>>>if (numbits<=sizeof(long)) return long;
>>>if (numbits<=sizeof(cent)) return cent;
>>>
>>>metathrow "Compiler error";
>>>}
>>>
>>>Or something like that.  The logic and intent of the above code is
>>>infinitely
>>>more clear to the reader than the C++ metaprogramming code linked to
>>>above.
>>>
>>>Obviously there are tons of issues to be worked out with making something
>>>like
>>>this work (syntax, what meta types are needed, compile-time error
>>>handling,
>>>etc), but it just seems to me that the past 7 or 8 years or so of work on
>>>C++
>>>template metaprogramming has proven that this stuff is useful, but it has
>>>also
>>>proven that to do anything useful with it you have to write pages of
>>>"write-only" code.  This stuff is so ugly that it sends people running to
>>>perl!
>>>:-P  Yes, it's that bad, folks. :-)
>>>
>>>Thoughts?  Any chances something like this could ever come to D?
>>>
>>>Bill Baxter
>>
>>This has been discussed, a little, on here before.  I think Walter said
>>he's had
>>email discussions and sees some promise in this direction or thereabouts,
>>but
>>I'm not positive.
>>
>>
>>But meta-programming is something that all modern optimizing compilers do
>>to a
>>*degree*.  They do it whenever you write code that can be unrolled and
>>precomputed.
>>
>>:int foo() {
>>:  int x = 5;
>>:  for(int j = 0; j<10; j++) {
>>:    x = x + j;
>>:  }
>>:  return x;
>>:}
>>
>>This could be a compiled loop.... Or, the compiler can unroll the loop and
>>do
>>ALL of it at compile time.
>>
>>What if there was a "version-like" statement that asked the compiler to do
>>this?
>>You could do something like:
>>
>>: compileTime {
>>:   char[] x = "abcd";
>>:   int abcd_hash = x[0] + x[1] + x[2] + x[3];
>>: }
>>
>>This would be something like the "inline" statement in C++.  Can the
>>compiler
>>really fold that string into an integer?  Will it?
>>
>>The compileTime{} pragma would essentially say "do this at compile time,
>>or
>>issue a warning if you can't".
>>
>>This solves the factorial problem:
>>
>>int factorial(int i) { /whatever/ };
>>
>>compileTime {
>>int x = factorial();
>>}
>>
>>compileTime{} would mean the compiler is expected to unroll loops, inline
>>every
>>function, and basically run the code at compile time.  If the above
>>"string"
>>example did not work (ie it used a user-provided string), then the
>>compileTime
>>statement fails with an error or warning.
>>
>>If reflection is added to the D language, then you could provide the
>>ability to
>>iterate over methods and fields, or build classes.  Combine reflection and
>>compileTime, and you can do template meta tasks.
>>
>>Kevin
>>
>>
>>
>
> 


May 05, 2005
Maybe, after compiling a program, the compiler can execute any function call that has constant (compile-time evaluable) arguments and replace the call with the return value.

It would simply execute the function after compiling, passing the constant arguments. This will result in another constant that will perhaps result in another function being evaluated compile-time, etc..

I think the nicest thing about meta-programming will be the possibility to introduce new operators. If we can add types, functions in code, why not also operators? You want "**" to mean "to the power of"? Just define it. "<=>" should call opCmp? Want to be able to do "&" on floats? Or maybe "^" should be "to the power of" if done on reals?

I can hardly wait!

L.


May 05, 2005
In article <d5cf7e$hh1$1@digitaldaemon.com>, Bill Baxter says...

>whereas it's always possible to just not inline something, it won't always be possible to not run some code at compile-time, say if the return value of the code is in fact a type rather than a number.  If you're working with types as data, then you absolutely can't run the code at runtime.

Depends how far reflection progresses, I think. If types were first-class objects, and

foo = new Foo();
foo.doStuff();

became (optimizable) syntactic sugar for

foo = ClassFoo.createNewObject();
ClassFoo.invokeMethod(foo, "doStuff");

then I don't see why this couldn't run at runtime.

>Oh, one final thing to throw into the mix -- special tag keywords. Things like 'synchronized' that change some aspect of how a method runs.

Agreed, but I'd prefer something like dotnet's attribute syntax:

[MyAttribute] someDeclaration

rather than keywords alone, just because it's so much more extensible - you don't need to be as conservative about introducing new ones.

- Mike


May 05, 2005
Heh heh.  Nice.  Now tell me how you propose to handle this one?

------------------------------
compileTime {
type integer(int numbits)
{
if (numbits<=sizeof(char)) return char;
if (numbits<=sizeof(short)) return short;
if (numbits<=sizeof(int)) return int;
if (numbits<=sizeof(long)) return long;
if (numbits<=sizeof(cent)) return cent;

throw "Compiler error";
}
}
integer(24) my24bitVar;
integer(40) my40bitVar;
------------------------------

And if you get that one, let us know how to tackle the binding generator problem.  I.e. Boost.python type functionality (http://www.boost.org/libs/python/doc/tutorial/doc/html/python/exposing.html) where to generate python bindings for a class (World) and a couple of its methods (greet and set) all you have to write is this little bit of C++:

class_<World>("World")
def("greet", &World::greet)
def("set", &World::set)
;

Since the compiler knows the number and types of arguments for World::greet it's possible for the above C++ code to generate complete typesafe wrappers to call these methods from python.  To get this kind of functionality, I think you're going to need to write a full D parser in php.  Should be fun!

--bb

In article <d5ch4n$jul$1@digitaldaemon.com>, Andrew Fedoniouk says...
>
>(not so) Wild idea  : to put your sources under httpd and config it for use lets say PHP processing on D files.
>
>So
>>>compileTime {
>>>int x = factorial();
>>>}
>
>will be just a
>
>int x = <% factorial(N) %>;
>
>This is reliable and can be used now.
>You even can assemble such preprocessor
>in D using DMDScript for example.
>
>Huh?
>I like my own idea :) The ultimate preprocessor.
>The way better as it clearly separates compile/runtime namespaces.
>And you can debug your meta and programs separately.
>And finally close this metaprogramming theme for now and beyond.



May 05, 2005
In article <d5d3c3$12ig$1@digitaldaemon.com>, Mike Capp says...
>
>In article <d5cf7e$hh1$1@digitaldaemon.com>, Bill Baxter says...
>
>>whereas it's always possible to just not inline something, it won't always be possible to not run some code at compile-time, say if the return value of the code is in fact a type rather than a number.  If you're working with types as data, then you absolutely can't run the code at runtime.
>
>Depends how far reflection progresses, I think. If types were first-class objects, and
>
>foo = new Foo();
>foo.doStuff();
>
>became (optimizable) syntactic sugar for
>
>foo = ClassFoo.createNewObject();
>ClassFoo.invokeMethod(foo, "doStuff");
>
>then I don't see why this couldn't run at runtime.


Ok.  Yeh, I'm not completely aware of what all is possible or in the works with D.  If D can support adding members to classes and things like that at run time, then there's probably not much that couldn't be shunted to run-time if need be. I was thinking D probably didn't have that sort of thing, being a speed-oriented compiled language.

>
>>Oh, one final thing to throw into the mix -- special tag keywords. Things like 'synchronized' that change some aspect of how a method runs.
>
>Agreed, but I'd prefer something like dotnet's attribute syntax:
>
>[MyAttribute] someDeclaration
>
>rather than keywords alone, just because it's so much more extensible - you don't need to be as conservative about introducing new ones.

Certainly.  That does sound better.  What kind of attributes can you define in NET?  Because after I wrote that I started thinking that maybe there aren't more than like 5 things you'd ever want to use that type of thing for. synchronized, scriptable... if D is going to have introspection, then you probably don't need signal or slot.  So hmm... I'm at two.  Oh "timed"? Automatically time the execution of a method?  Maybe some contract programming or aspect oriented programming things?

--bb


« First   ‹ Prev
1 2 3 4 5 6 7 8