[stringtemplate-interest] Understanding template recursion

Trevor Strohman strohman at cs.umass.edu
Thu May 24 08:11:38 PDT 2007


John,

> recurse(x) ::= "<x><rest(x):recurse()>"
>
> In this case on the first call x is the whole list so "abcd" is  
> output. then it loops over the rest of x calling recurse with the x  
> being the current item it. It is the same as recurse(x=it).
> When I try this I get "abcdbcd"
> For me this is behaving as you and I would expect. I don't know why  
> it doesn't work for you. We may have different versions of ST.
>

I typed my e-mail too quickly--what I actually tested was:
	recurse(x) ::= "<first(x)><rest(x):recurse()>"
	recurse2(x) ::= "<first(x)><recurse2(rest(x))>"

I do understand why recurse(x) works the way it does, now.  Terrence  
has this version:
	recurse(x) ::= "<x><rest(x):recurse()>"
on a presentation slide about recursion, although it's really just a  
single level of recursion, not tail recursion (which I was expecting).

> recurse2(x) ::= "<x><recurse2(rest(x))>"
>
> I think what might be happening here is infinite recursion.
>

I think so too, since I get a stack overflow error, but I also found  
(as you did) that guarding it with an ifdef didn't seem to work.


> [explanation of a bug omitted]
> Iterators should never be passed to templates. This bug will  
> prevent you from doing anything interesting with recursive templates.
>

That's too bad.  I guess I'll try to work around the issue.

What I'm really trying to do is output nested loops.  If my list is  
a,b,c,d, I want, for example:
	for( int ai=0; ai<a; ai++ ) {
		for( int bi=0; bi<b; bi++ ) {
			for( int ci=0; ci<c; ci++ ) {
				for( int di; di<d; di++ ) {
					...
				}
			}
		}
	}

I can work around it by making each loop a different method in the  
exported code, like:
	for( int ai=0; ai<a; ai++ ) {
		bLoop(ai);
	}
and I can change my model so that I have a.next = b, b.next = c,  
c.next = d.  I prefer the nested loop, though.

Thanks for your help.


> P.S. I went to umass Amherst back in the 80's.
>

Good to hear from an alumnus!

Trevor

> Trevor Strohman wrote:
>
>> I'm having trouble understanding recursion in templates.
>>
>> Suppose I have a list called "items" that contains Strings: "a",  
>> "b",  "c", "d", and these two templates:
>> recurse(x) ::= "<x><rest(x):recurse()>"
>> recurse2(x) ::= "<x><recurse2(rest(x))>"
>>
>> I expect <recurse(items)> to become:
>> 	abcdcdd
>> and <recurse2(items)> to become:
>> 	abcd
>>
>> However, <recurse(items)> becomes "abcd" and <recurse2(items)>  
>> throws  an Exception.  What am I misunderstanding?
>>
>> Also, I notice that functions first, last and rest don't seem to  
>> be  first-class citizens in the language.  These expressions  
>> throw  exceptions:
>> 	<if(first(rest(items))>
>> 	<first(items).isEnabled>
>> This has been a problem for me this afternoon.  I feel like I must  
>> be  misunderstanding the right way to approach recursive template   
>> invocation.
>>
>> Trevor
>>
>> _______________________________________________
>> stringtemplate-interest mailing list
>> stringtemplate-interest at antlr.org
>> http://www.antlr.org:8080/mailman/listinfo/stringtemplate-interest
>>
>>
>>




More information about the stringtemplate-interest mailing list