www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - program for building the program

reply Gzp <galap freemail.hu> writes:
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
parent reply "Nick Sabalausky" <a a.a> writes:
"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
next sibling parent reply "Denis Koroskin" <2korden gmail.com> writes:
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...
 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.
FWIW, Descent already capable of doing this: http://www.youtube.com/watch?v=oAhrFQVnsrY
Dec 01 2009
next sibling parent "Nick Sabalausky" <a a.a> writes:
"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:

 "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.
FWIW, Descent already capable of doing this: http://www.youtube.com/watch?v=oAhrFQVnsrY
Yea, but then I'd have to use Eclipse ;)
Dec 01 2009
prev sibling next sibling parent gzp <galap freemail.hu> writes:
Denis Koroskin írta:
 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...
 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.
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.

 
 FWIW, Descent already capable of doing this:
 
 http://www.youtube.com/watch?v=oAhrFQVnsrY
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. Gzp
Dec 01 2009
prev sibling parent reply BCS <none anon.com> writes:
Hello Denis,

 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...
 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.
FWIW, Descent already capable of doing this: http://www.youtube.com/watch?v=oAhrFQVnsrY
That's not much help when the program I write crash Descent. :) (OTOH I'm not most people)
Dec 01 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
BCS wrote:
 Hello Denis,
 
 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...
 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.
FWIW, Descent already capable of doing this: http://www.youtube.com/watch?v=oAhrFQVnsrY
That's not much help when the program I write crash Descent. :) (OTOH I'm not most people)
I think the dynamic bit that D lacks and many interpreters have is eval(someString). Andrei
Dec 01 2009
parent reply "Joel C. Salomon" <joelcsalomon gmail.com> writes:
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
parent Bill Baxter <wbaxter gmail.com> writes:
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:
 I think the dynamic bit that D lacks and many interpreters have is
 eval(someString).
I wonder if ddmd can be shoehorned into that=85
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(= ). --bb
Dec 01 2009
prev sibling parent reply gzp <galap freemail.hu> writes:
 "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.
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).
 
 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.
Gzp
Dec 01 2009
parent reply "Nick Sabalausky" <a a.a> writes:
"gzp" <galap freemail.hu> wrote in message 
news:hf3dag$12b8$1 digitalmars.com...
 "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.
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.
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); }
Dec 01 2009
parent gzp <galap freemail.hu> writes:
 
 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