digitalmars.D - Groovy Templates for D?
- David Medlock (33/33) May 30 2005 I program web/Oracle apps in Java for $$ and therefore attempt to make
- Walter (2/2) May 30 2005 I think D can do what you're asking with function literals and delegate
- David Medlock (2/6) May 31 2005 ok :)
- Jarrett Billingsley (19/21) May 31 2005 I think what he's asking is that for a function such as:
- David Medlock (5/37) May 31 2005 Exactly. Since I cannot think of an ambiguity with a code block
- Georg Wrede (21/56) Jun 01 2005 This is yet another example of language constructs that are useful and
- Sean Kelly (12/48) Jun 01 2005 void func( int a, float b );
- David Medlock (26/90) Jun 01 2005 I was advocating this only for templates with an explicit delegate as
- David Medlock (6/115) Jun 01 2005 As a quick follow up, I think that if this syntactical change were
- Sean Kelly (3/7) Jun 01 2005 Scratch this. Anonymous delegates obviously don't take parameters :p
I program web/Oracle apps in Java for $$ and therefore attempt to make the situation as good(programming-power wise) as I can. I recently dumped both velocity(a templating engine) and Struts(a Web framework) for the recently Sun-standardized Groovy language. (the point is coming, keep reading) It is quite frankly the most powerful language I've used yet for the JVM. The implementation has a few dark corners but it has excellent power-to-usability. The *best* feature I have found so far is how the language can be expanded using Java classes. Basically any function call can include an attached body of code which is called a Closure(very close to a D delegate) as the last argument. This is incredible expandibility. For instance suppose I want to be able to do the following: for(10) { print( "Hello" ); } then I would use the following Java function. void for( int n, Closure cl ) { while( n>0 ) { cl(); n--; } } For Html its even better: void form( Closure cl ) { write("<form>"); cl(); write("</form>"); } then in script: form() { out.write( "<input..."); } I am wondering if this is feasible for D. It would expand by orders of magnitude the language and make C-macros seem pretty silly(combined with the version system). Syntax I would propose: template Foo( alias int n, body f ) { void Foo() { while ( n>0 ) { n--; f(); } } } Foo!(100) { writefln("Hello World"); } Perhaps this wouldnt add a ton, but....thoughts? -DavidM
May 30 2005
I think D can do what you're asking with function literals and delegate literals.
May 30 2005
Walter wrote:I think D can do what you're asking with function literals and delegate literals.ok :)
May 31 2005
"Walter" <newshound digitalmars.com> wrote in message news:d7gp1s$msm$1 digitaldaemon.com...I think D can do what you're asking with function literals and delegate literals.I think what he's asking is that for a function such as: void fork(int x, int y, void delegate() dg) { writefln(x); writefln(y); dg(); } If you were to use the function like so: fork(5,10) { writefln("delegate!"); } It would implicitly be converted to fork(5,10,void delegate() { writefln("delegate!"); }); The key being the implicit conversion of the immediately-following block of code into the last parameter. A minor feature, and probably would have very limited usefulness, but it's interesting nonetheless.
May 31 2005
Jarrett Billingsley wrote:"Walter" <newshound digitalmars.com> wrote in message news:d7gp1s$msm$1 digitaldaemon.com...Exactly. Since I cannot think of an ambiguity with a code block appearing after a template it would seem a nice bit of syntactical convenience. -DavidMI think D can do what you're asking with function literals and delegate literals.I think what he's asking is that for a function such as: void fork(int x, int y, void delegate() dg) { writefln(x); writefln(y); dg(); } If you were to use the function like so: fork(5,10) { writefln("delegate!"); } It would implicitly be converted to fork(5,10,void delegate() { writefln("delegate!"); }); The key being the implicit conversion of the immediately-following block of code into the last parameter. A minor feature, and probably would have very limited usefulness, but it's interesting nonetheless.
May 31 2005
David Medlock wrote:Jarrett Billingsley wrote:This is yet another example of language constructs that are useful and powerful, but which may be used only by advanced programmers. Implementing this kind of stuff ends up cluttering the syntax space, as well as bloating the compiler, because each of these (admittedly good) features would be implemented more or less separately. That tends to create interdependencies and barriers in - compiler source - language semantics - language syntax The Metalanguage (search for my posts in d.D around Feb/March) would take care of this kind of issues. (Among other things.) Instead of implementing quite a few things directly in the compiler, or the language itself, we would be better off having a mechanism with which this and other things could be created by the programmer as the need arises. I'm actually working on this since some time, but don't expect any real results before Q4. ---- Currently I'm not as free to do D stuff as I was earlier this year, but I'm still at it, in the background."Walter" <newshound digitalmars.com> wrote in message news:d7gp1s$msm$1 digitaldaemon.com...Exactly. Since I cannot think of an ambiguity with a code block appearing after a template it would seem a nice bit of syntactical convenience.I think D can do what you're asking with function literals and delegate literals.I think what he's asking is that for a function such as: void fork(int x, int y, void delegate() dg) { writefln(x); writefln(y); dg(); } If you were to use the function like so: fork(5,10) { writefln("delegate!"); } It would implicitly be converted to fork(5,10,void delegate() { writefln("delegate!"); }); The key being the implicit conversion of the immediately-following block of code into the last parameter. A minor feature, and probably would have very limited usefulness, but it's interesting nonetheless.
Jun 01 2005
In article <d7itg7$44m$1 digitaldaemon.com>, David Medlock says...Jarrett Billingsley wrote:void func( int a, float b ); void func( int a, float b, void delegate() ); func( 1, 1.0 ) { } Which function gets called by the above? Also, how would: // accepts a delegate with parameters void func( int a, float b, void delegate( int c ) ); be represented using the above method? I grant it's a cool idea, but the solution to both of these issues isn't obvious to me. Sean"Walter" <newshound digitalmars.com> wrote in message news:d7gp1s$msm$1 digitaldaemon.com...Exactly. Since I cannot think of an ambiguity with a code block appearing after a template it would seem a nice bit of syntactical convenience.I think D can do what you're asking with function literals and delegate literals.I think what he's asking is that for a function such as: void fork(int x, int y, void delegate() dg) { writefln(x); writefln(y); dg(); } If you were to use the function like so: fork(5,10) { writefln("delegate!"); } It would implicitly be converted to fork(5,10,void delegate() { writefln("delegate!"); }); The key being the implicit conversion of the immediately-following block of code into the last parameter. A minor feature, and probably would have very limited usefulness, but it's interesting nonetheless.
Jun 01 2005
Sean Kelly wrote:In article <d7itg7$44m$1 digitaldaemon.com>, David Medlock says...I was advocating this only for templates with an explicit delegate as the last parameter, like my Java examples. So you would need: func!( 1, 10 ) { ... } there is still nothing stopping you from calling: func!( 1, 10, delegate { ... } ); For the parameters, I admit I don't have a solution. In Groovy you can specify: myfunction = { a, b -> print(a); print(b); ... } ... myfunction( 100, 200 ) In response to George, I disagree it is syntactical clutter. There are 3 basic uses for templates and macros in general: 1. Generation of type dependent meta-types (aka specialized classes). 2. Generation of type dependent functions (polymorphic behavior dispatched on type, rather than value) 3. _Execution_ of code dispatched on passed types or values. dangerous!) abilities. Usually by introducing a new block which allows local variables, etc. I believe this syntactical addition would close the gap between what C-macros can do and do it in a safer way. This is not to say your Metalanguage would not, just disagree with the 'clutter' statement. Its not a huge deal, but this type of thing is quite useful in Groovy. -DavidMJarrett Billingsley wrote:void func( int a, float b ); void func( int a, float b, void delegate() ); func( 1, 1.0 ) { } Which function gets called by the above? Also, how would: // accepts a delegate with parameters void func( int a, float b, void delegate( int c ) ); be represented using the above method? I grant it's a cool idea, but the solution to both of these issues isn't obvious to me. Sean"Walter" <newshound digitalmars.com> wrote in message news:d7gp1s$msm$1 digitaldaemon.com...Exactly. Since I cannot think of an ambiguity with a code block appearing after a template it would seem a nice bit of syntactical convenience.I think D can do what you're asking with function literals and delegate literals.I think what he's asking is that for a function such as: void fork(int x, int y, void delegate() dg) { writefln(x); writefln(y); dg(); } If you were to use the function like so: fork(5,10) { writefln("delegate!"); } It would implicitly be converted to fork(5,10,void delegate() { writefln("delegate!"); }); The key being the implicit conversion of the immediately-following block of code into the last parameter. A minor feature, and probably would have very limited usefulness, but it's interesting nonetheless.
Jun 01 2005
David Medlock wrote:Sean Kelly wrote:As a quick follow up, I think that if this syntactical change were implemented (kinks worked out), it would make foreach/opApply implementable in Phobos as a template specializing on Object or array types! foreach!( int item, int[] array ) { ... } -DavidMIn article <d7itg7$44m$1 digitaldaemon.com>, David Medlock says...I was advocating this only for templates with an explicit delegate as the last parameter, like my Java examples. So you would need: func!( 1, 10 ) { ... } there is still nothing stopping you from calling: func!( 1, 10, delegate { ... } ); For the parameters, I admit I don't have a solution. In Groovy you can specify: myfunction = { a, b -> print(a); print(b); ... } ... myfunction( 100, 200 ) In response to George, I disagree it is syntactical clutter. There are 3 basic uses for templates and macros in general: 1. Generation of type dependent meta-types (aka specialized classes). 2. Generation of type dependent functions (polymorphic behavior dispatched on type, rather than value) 3. _Execution_ of code dispatched on passed types or values. dangerous!) abilities. Usually by introducing a new block which allows local variables, etc. I believe this syntactical addition would close the gap between what C-macros can do and do it in a safer way. This is not to say your Metalanguage would not, just disagree with the 'clutter' statement. Its not a huge deal, but this type of thing is quite useful in Groovy. -DavidMJarrett Billingsley wrote:void func( int a, float b ); void func( int a, float b, void delegate() ); func( 1, 1.0 ) { } Which function gets called by the above? Also, how would: // accepts a delegate with parameters void func( int a, float b, void delegate( int c ) ); be represented using the above method? I grant it's a cool idea, but the solution to both of these issues isn't obvious to me. Sean"Walter" <newshound digitalmars.com> wrote in message news:d7gp1s$msm$1 digitaldaemon.com...Exactly. Since I cannot think of an ambiguity with a code block appearing after a template it would seem a nice bit of syntactical convenience.I think D can do what you're asking with function literals and delegate literals.I think what he's asking is that for a function such as: void fork(int x, int y, void delegate() dg) { writefln(x); writefln(y); dg(); } If you were to use the function like so: fork(5,10) { writefln("delegate!"); } It would implicitly be converted to fork(5,10,void delegate() { writefln("delegate!"); }); The key being the implicit conversion of the immediately-following block of code into the last parameter. A minor feature, and probably would have very limited usefulness, but it's interesting nonetheless.
Jun 01 2005
In article <d7kg95$1pqa$1 digitaldaemon.com>, Sean Kelly says...Also, how would: // accepts a delegate with parameters void func( int a, float b, void delegate( int c ) ); be represented using the above method?Scratch this. Anonymous delegates obviously don't take parameters :p Sean
Jun 01 2005