View mode: basic / threaded / horizontal-split · Log in · Help
May 30, 2005
Groovy Templates for D?
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 31, 2005
Re: Groovy Templates for D?
I think D can do what you're asking with function literals and delegate
literals.
May 31, 2005
Re: Groovy Templates for D?
Walter wrote:
> I think D can do what you're asking with function literals and delegate
> literals.
> 
> 
ok :)
May 31, 2005
Re: Groovy Templates for D?
"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
Re: Groovy Templates for D?
Jarrett Billingsley wrote:

> "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. 
> 
> 
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.

-DavidM
June 01, 2005
Re: Groovy Templates for D?
David Medlock wrote:
> Jarrett Billingsley wrote:
> 
>> "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.
>>
> 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.

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.
June 01, 2005
Re: Groovy Templates for D?
In article <d7itg7$44m$1@digitaldaemon.com>, David Medlock says...
>
>Jarrett Billingsley wrote:
>
>> "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. 
>> 
>> 
>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.

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
June 01, 2005
Re: Groovy Templates for D?
Sean Kelly wrote:
> In article <d7itg7$44m$1@digitaldaemon.com>, David Medlock says...
> 
>>Jarrett Billingsley wrote:
>>
>>
>>>"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. 
>>>
>>>
>>
>>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.
> 
> 
> 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
> 
> 
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.

#3 is the speciality of C-macros and allows various powerful(but 
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.
-DavidM
June 01, 2005
Re: Groovy Templates for D?
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
June 01, 2005
Re: Groovy Templates for D?
David Medlock wrote:
> Sean Kelly wrote:
> 
>> In article <d7itg7$44m$1@digitaldaemon.com>, David Medlock says...
>>
>>> Jarrett Billingsley wrote:
>>>
>>>
>>>> "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.
>>>>
>>>
>>> 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.
>>
>>
>>
>> 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
>>
>>
> 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.
> 
> #3 is the speciality of C-macros and allows various powerful(but 
> 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.
> -DavidM
> 
> 

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 ) { ... }

-DavidM
Top | Discussion index | About this forum | D home