[stringtemplate-interest] Understanding template recursion
John Snyders
jjsnyders at rcn.com
Wed May 23 20:26:22 PDT 2007
One more note on this.
I thought I could get around the problem by using the literal list
construction to force a new list to be created
as in
recurse2(x) ::= "$x$ $if(x)$$recurse2([rest(x)])$$endif$"
or
$useItTwice([rest(items)])$
But this does not help because the list construct returns an iterator as
well
In ActionEvaluator.java: list method
value = new CatIterator(elements);
...
return value;
This too will need to be fixed.
-John
John Snyders wrote:
> Hi Trevor,
>
> 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.
>
> recurse2(x) ::= "<x><recurse2(rest(x))>"
>
> I think what might be happening here is infinite recursion. The typical
> pattern for recursion is to have a test for the case that is going to
> stop the recursion. You might intend something like this (I just happen
> to use $$ rather than <>)
>
> recurse2(x) ::= "$x$ $if(x)$$recurse2(rest(x))$$endif$"
>
> Sadly this does not do what I expect. The first time it should output
> "abcd" because x is items. Now it calls recurse2 with the rest of x
> which is [ b, c, d ] and that is what should be output next "bcd" Now it
> recurses again with [ c, d ] and should output "cd" and again resulting
> in "d" at which point rest is null and the if would be false. So the
> total output I expect is "abcd bcd cd d "
>
> What I get is "abcd bcd "
>
> The reason I believe has to do with how ST uses iterators. On the first
> recursive call to recurse2(rest(x)) rest(x) returns an iterator and not
> a new list that is a slice of the old list. Now on the recursive call x
> is an iterator and as soon as you use it once it is used up. The next
> recursive call rest(x) returns null because x was used up in $x$.
>
> This is a very serious bug and I thought I had reported it before in
> some way but now I can't find it in the archives.
> A very simple way to see this bug is with the following
> useItTwice(x) ::= <<
> once : $x;separator=", "$
> twice: $x;separator=", "$
> >>
> test() ::= <<
> $useItTwice(items)$
> $useItTwice(rest(items))$
> >>
> With your definition of items calling
> $useItTwice(items)$
> $useItTwice(rest(items))$
> it should print
> once : a, b, c, d
> twice: a, b, c, d
> once : b, c, d
> twice: b, c, d
>
> but it prints
> once : a, b, c, d
> twice: a, b, c, d
> once : b, c, d
> twice:
>
> Iterators should never be passed to templates. This bug will prevent you
> from doing anything interesting with recursive templates.
>
> P.S. I went to umass Amherst back in the 80's.
>
> -John
>
> 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
>>
>>
>>
> _______________________________________________
> 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