digitalmars.D - program for building the program
- Gzp (37/37) Dec 01 2009 Just some ideas without any proposal. Some time back on the university
- Nick Sabalausky (13/17) Dec 01 2009 The problem with that, aside from the increase in the grammar's complexi...
- Denis Koroskin (3/10) Dec 01 2009 FWIW, Descent already capable of doing this:
- Nick Sabalausky (3/16) Dec 01 2009 Yea, but then I'd have to use Eclipse ;)
- gzp (29/45) Dec 01 2009 Yes this is what I've meant and also a way to document the generated
- BCS (3/20) Dec 01 2009 That's not much help when the program I write crash Descent. :) (OTOH I'...
- Andrei Alexandrescu (4/28) Dec 01 2009 I think the dynamic bit that D lacks and many interpreters have is
- Joel C. Salomon (3/5) Dec 01 2009 I wonder if ddmd can be shoehorned into that…
- Bill Baxter (6/11) Dec 01 2009 Only if you make the whole compiler part of the runtime library.
- gzp (14/37) Dec 01 2009 OK, CTFE is an optimization question for me. It is not the template,
- Nick Sabalausky (18/40) Dec 01 2009 CTFE is used for optimization, but it is *also* used for metaprogramming...
- gzp (17/39) Dec 01 2009 In this context it is a function to generate code and this code won't be...
Just some ideas without any proposal. Some time back on the university we've learned of 2 layered languages( not sure of the name) from formal semantics. It occurred to me all this CTFE, template, mixin things are just an implementation of the mentioned semantics. So to designing template(generic) code, a simplified language should be created that generates the actual source. So the border b/n the two language can be made more explicit and fewer questions arose. The semantic is an adhoc, only the idea is important, to specify the language for creating codes: // block to generate the code !template MyTemplate(T) { !for i in ["*","+","-"] { !if( T is builin type ) { !// performs the !i operation on a and b T op!i (T a T b) { return a !i b } } !else { T op!i (T a T b) { return a.op!i( b ) } } // error as when the generator is invoked, a single if is generated without a block //if( true ) //writeln("aaa"); } } // invoking the code genertor MyTemplate!(int) MyTemplate!(BigInt) Maybe it's treated like this and has the same view in the head of everybody, but for me it was not stated like this before. The compiler also should provide readably output of the generated code. ex. generated documentation of the generated code (see the !// comment in the sample) Regards, Gzp
Dec 01 2009
"Gzp" <galap freemail.hu> wrote in message news:hf2k9a$2l54$1 digitalmars.com...So to designing template(generic) code, a simplified language should be created that generates the actual source. So the border b/n the two language can be made more explicit and fewer questions arose.The problem with that, aside from the increase in the grammar's complexity, is that anytime you want to be able to do something at both runtime and compile-time, you'd have to write two separate implementations of the same thing, which carries with it all the problems assisiated with breaking DRY. Plus then that would create a need to write meta-meta-functions that generate both the runtime and compile-time versions of the same function. CTFE (and better yet, Nemerle's way, at least from what I've seen of it), is just a better approach.The compiler also should provide readably output of the generated code.I'm not sure if this is what you mean, but I definitely want a compiler switch that outputs the resulting D code after all the mixins and such are applied.
Dec 01 2009
On Tue, 01 Dec 2009 17:02:40 +0300, Nick Sabalausky <a a.a> wrote:"Gzp" <galap freemail.hu> wrote in message news:hf2k9a$2l54$1 digitalmars.com...FWIW, Descent already capable of doing this: http://www.youtube.com/watch?v=oAhrFQVnsrYThe compiler also should provide readably output of the generated code.I'm not sure if this is what you mean, but I definitely want a compiler switch that outputs the resulting D code after all the mixins and such are applied.
Dec 01 2009
"Denis Koroskin" <2korden gmail.com> wrote in message news:op.u39iv5dco7cclz dkoroskin.saber3d.local...On Tue, 01 Dec 2009 17:02:40 +0300, Nick Sabalausky <a a.a> wrote:Yea, but then I'd have to use Eclipse ;)"Gzp" <galap freemail.hu> wrote in message news:hf2k9a$2l54$1 digitalmars.com...FWIW, Descent already capable of doing this: http://www.youtube.com/watch?v=oAhrFQVnsrYThe compiler also should provide readably output of the generated code.I'm not sure if this is what you mean, but I definitely want a compiler switch that outputs the resulting D code after all the mixins and such are applied.
Dec 01 2009
Denis Koroskin írta:On Tue, 01 Dec 2009 17:02:40 +0300, Nick Sabalausky <a a.a> wrote:Yes this is what I've meant and also a way to document the generated codes in a more readable form. Ex. for a matrix (planned to) have multiple additions depending on the matrix representation and each have a different property (like performance) that the user should be aware of. The actual functions the user calls are generated by mixins and it's quite difficult to find out what is called exactly. So from a documentation view it'd be great to document the (auto)generated code."Gzp" <galap freemail.hu> wrote in message news:hf2k9a$2l54$1 digitalmars.com...The compiler also should provide readably output of the generated code.I'm not sure if this is what you mean, but I definitely want a compiler switch that outputs the resulting D code after all the mixins and such are applied.It looks great to develop the library, but as a user of a library most certainly I'm not interested how the code is expanded I just want to now what function/class to use and what parameters it requires. (Though I really liked the idea). ex: package template DefineUnary(string tName, string tFunction) { const char[] code = "void " ~ tName ~ "(T)( ref T p ) { " ~ "UnaryOperation!(\""~ tFunction~ "\").inPlace( p ); }" ~ "void " ~ tName ~ "(T1, T2)( const T1 p1, ref T2 p2 ) { " ~ "UnaryOperation!(\""~ tFunction~ "\").copy( p1,p2 ); }"; } mixin( DefineUnary!("neg", "-a" ).code ); mixin( DefineUnary!("twice", "2*a" ).code ); mixin( DefineUnary!("triple", "3*a" ).code ); It's quite hard to find out what is the function actually. Not only the parameters but the function name is not trivial at all. Note: There might be better solutions for this. GzpFWIW, Descent already capable of doing this: http://www.youtube.com/watch?v=oAhrFQVnsrY
Dec 01 2009
Hello Denis,On Tue, 01 Dec 2009 17:02:40 +0300, Nick Sabalausky <a a.a> wrote:That's not much help when the program I write crash Descent. :) (OTOH I'm not most people)"Gzp" <galap freemail.hu> wrote in message news:hf2k9a$2l54$1 digitalmars.com...FWIW, Descent already capable of doing this: http://www.youtube.com/watch?v=oAhrFQVnsrYThe compiler also should provide readably output of the generated code.I'm not sure if this is what you mean, but I definitely want a compiler switch that outputs the resulting D code after all the mixins and such are applied.
Dec 01 2009
BCS wrote:Hello Denis,I think the dynamic bit that D lacks and many interpreters have is eval(someString). AndreiOn Tue, 01 Dec 2009 17:02:40 +0300, Nick Sabalausky <a a.a> wrote:That's not much help when the program I write crash Descent. :) (OTOH I'm not most people)"Gzp" <galap freemail.hu> wrote in message news:hf2k9a$2l54$1 digitalmars.com...FWIW, Descent already capable of doing this: http://www.youtube.com/watch?v=oAhrFQVnsrYThe compiler also should provide readably output of the generated code.I'm not sure if this is what you mean, but I definitely want a compiler switch that outputs the resulting D code after all the mixins and such are applied.
Dec 01 2009
On 12/1/2009 3:21 PM, Andrei Alexandrescu wrote:I think the dynamic bit that D lacks and many interpreters have is eval(someString).I wonder if ddmd can be shoehorned into that… —Joel Salomon
Dec 01 2009
On Tue, Dec 1, 2009 at 1:35 PM, Joel C. Salomon <joelcsalomon gmail.com> wr= ote:On 12/1/2009 3:21 PM, Andrei Alexandrescu wrote:Only if you make the whole compiler part of the runtime library. Or at least the CTFE code-interpreting subset of it, to get a limited eval(= ). --bbI think the dynamic bit that D lacks and many interpreters have is eval(someString).I wonder if ddmd can be shoehorned into that=85
Dec 01 2009
"Gzp" <galap freemail.hu> wrote in message news:hf2k9a$2l54$1 digitalmars.com...OK, CTFE is an optimization question for me. It is not the template, mixin part of the language. This meta-programming let's you to generates codes where you'd use cut/past/replace in a much safer, cleaner way. In CTFE you can give hints to the compiler: hey, please evaluate this piece of code and substitute only the result. Like in Clean (fully functional programming language) the actual calculation takes place in the compiler as much as it can. And no, I would not allow CTFE codes to be present in the first layer (as expression to be evaluated). The compiled program in Clean for printing the first 100 digit of PI writes out just a string(number) and performs no calculation (in theory, but I'm not sure what's going on in practice, I haven't written that much Clean code).So to designing template(generic) code, a simplified language should be created that generates the actual source. So the border b/n the two language can be made more explicit and fewer questions arose.The problem with that, aside from the increase in the grammar's complexity, is that anytime you want to be able to do something at both runtime and compile-time, you'd have to write two separate implementations of the same thing, which carries with it all the problems assisiated with breaking DRY. Plus then that would create a need to write meta-meta-functions that generate both the runtime and compile-time versions of the same function. CTFE (and better yet, Nemerle's way, at least from what I've seen of it), is just a better approach.GzpThe compiler also should provide readably output of the generated code.I'm not sure if this is what you mean, but I definitely want a compiler switch that outputs the resulting D code after all the mixins and such are applied.
Dec 01 2009
"gzp" <galap freemail.hu> wrote in message news:hf3dag$12b8$1 digitalmars.com...CTFE is used for optimization, but it is *also* used for metaprogramming: char[] genDecl(char[][] names) { char[] ret; foreach(char[] name; names) ret ~= "int "~name~";"; return ret; } void main() { mixin( genDecl( ["foo"[], "a", "b"] ) ); a = 2; b = 3; foo = a + b; assert(foo == 5); }"Gzp" <galap freemail.hu> wrote in message news:hf2k9a$2l54$1 digitalmars.com...OK, CTFE is an optimization question for me. It is not the template, mixin part of the language. This meta-programming let's you to generates codes where you'd use cut/past/replace in a much safer, cleaner way. In CTFE you can give hints to the compiler: hey, please evaluate this piece of code and substitute only the result. Like in Clean (fully functional programming language) the actual calculation takes place in the compiler as much as it can.So to designing template(generic) code, a simplified language should be created that generates the actual source. So the border b/n the two language can be made more explicit and fewer questions arose.The problem with that, aside from the increase in the grammar's complexity, is that anytime you want to be able to do something at both runtime and compile-time, you'd have to write two separate implementations of the same thing, which carries with it all the problems assisiated with breaking DRY. Plus then that would create a need to write meta-meta-functions that generate both the runtime and compile-time versions of the same function. CTFE (and better yet, Nemerle's way, at least from what I've seen of it), is just a better approach.
Dec 01 2009
CTFE is used for optimization, but it is *also* used for metaprogramming: char[] genDecl(char[][] names) { char[] ret; foreach(char[] name; names) ret ~= "int "~name~";"; return ret; } void main() { mixin( genDecl( ["foo"[], "a", "b"] ) ); a = 2; b = 3; foo = a + b; assert(foo == 5); }In this context it is a function to generate code and this code won't be ever called as a normal function. I've been thinking of functions where the code is invoked as a meta-programming code and as a normal function as well, but couldn't find any good example. - some pre-calculated constants (immutable) const real pi = calculatePi(); (immutable) const BigInt int = calculatePi( 100000 ); - a piece of code as in the example before - I don't see too much use of codes like this: int[ calcule_number_of_zero_position() ] zero_positions; They may provide some performance gain, but usually the size can be found out without complex ctfe. (Unless one is writing a compile time tracer) Though I know there's no much chance that D2 is altered, but I think it'd help both the compiler (including complexity and speed issues), the language specification (simplifies) and the readability of the resulting sources if the two layers are distinct and not intermixed as now.
Dec 01 2009