[stringtemplate-interest] [ST4 Beta4] Default args are not always evaluated in the context of their template

Udo Borkowski ub at abego-software.de
Thu Feb 17 03:03:46 PST 2011


Ter wrote in a recent mail:

> In ST v4, the default args are formally defined to have the same context as the template itself, hence, default arguments can see the other arguments.
> 


Based on this I expected the default args are also evaluated in the context of the template, e.g. if t1 is defined as

	t1(p1,p2={<p1>}) ::= <<…>>

and I call

	<t1(p1="A")>

p1 and p2 both will have the value "A". 

As it turns out this is not always the case.


When the name "p1" is later used in a different template called inside of t1 the new value of p1 is also applied to the default arg (and not the value defined in the context of t1). 

Here a complete example:

-----------
t1(p1,p2={<p1>}) ::= <<
  inside t1: p1=<p1>, p2=<p2>
<t2(p1="B",p2=p2)>
>>

t2(p1,p2) ::= <<
  inside t2: p1=<p1>, p2=<p2>
>>

main() ::= <<
Use default value for p2
<t1(p1="A")>
>> 
------------

This will output:
-------------
Use default value for p2
  inside t1: p1=A, p2=A
  inside t2: p1=B, p2=B
----------

However I had expected:
-------------
Use default value for p2
  inside t1: p1=A, p2=A
  inside t2: p1=B, p2=A
----------

i.e. I expected p2 to be "A" in the template t2, too, as this is the default value defined in the context of t1.

It looks like the names in a default value expression/subtemplate are resolved the "normal" way by dynamically looking up the call chain for the name, starting "at the current scope", i.e. "the point when the default value template is currently expanded". I expected the lookup starts with the template argument definition in t1(p1,p2={<p1>}). If this fails a "normal" lookup may be performed.

I know one could "fix" the above example by changing the definition of t1 from

	t1(p1,p2={<p1>}) ::= <<…>>
to 
	t1(p1,p2={<(p1)>}) ::= <<…>>

i.e. force to "stringify" the default value in the argument definition. 

However 
a) I am not sure if this is obvious for the "casual user".  (BTW: is this "{<(p1)>}" behavior documented somewhere? I learned this by reading the source code.)

b) this does not work in all cases. E.g. the template definition

	t3(p1,p2={<p1>x}) ::= <<…>>

(i.e. append an "x" to the value of p1 to create p2) could not be fixed this way.


To fix the issue I assume one needs to remember the context of the default value subtemplate (i.e. the argument list) with the subtemplate instance and check this context first before doing the normal dynamic name lookup.


Udo



More information about the stringtemplate-interest mailing list