[antlr-interest] Organization of complex template structures

Peter Stirling peter at pjstirling.plus.com
Sun Dec 21 03:20:20 PST 2008


It appears that the 'expected' use of StringTemplate is that templates  
used together are all written by a single organisation, if not single  
programmer, am I wrong in this belief? That composition through  
inheritance is available, but existing only for replacing elements in  
ways that both parent and child groups are aware will happen?


My understanding of what he has brought up is that template groups  
don't appear to support programming in-the-large.

I have a web-site, while writing the actual content I also build a  
library of templates that do html in my style.

	Libraries are good.

If I want to write a second web-site which re-uses these short-cuts  
then the stringtemplate 'way' is to move the shared elements into  
their own group and then both sites will need to inherit from this  
group.

Fictitious example ahoy!

A site creator wishes to use two libraries, one for pure html  
convenience, the second with useful trivia about all things nautical.  
Neither library was written by our hapless author.
StringTemplate currently only offers single-inheritance for group  
composition, and it should be fairly obvious that these groups do not  
share a meaningful inheritance relationship (but as StringTemplate  
only offers single inheritance then you would be forced to linear-ise  
a relationship between them and the client templates favouring one or  
the other). Worse is yet to come.

The html library contains a $anchor()$ template which does various  
sensible things with urls.

The nautical library has a $anchor()$ template that evaluates to  
description in agonising detail of the various forms of metal hooks  
used for tethering ships.

By changing the order of inheritance you can decide which template  
will 'win', but if the goal is to access both in different contexts  
then your only recourse is a manual rename of one of them. These  
libraries are unlikely to have been written by the same person  
(otherwise the names wouldn't conflict) this means that new versions  
of either library will require our hapless author to find out whether  
new template name conflicts have occurred and then perform more manual  
renames (in addition to any that he identified from previous versions).

For this use-case it makes sense (to me) to have a different kind of  
group that you can inherit from, one that will recognise a prefix  
(that the client templates will use) that maps to a particular group,  
from which to return the actual template instance.

Something along the lines of:

bag = new StringTemplateGroupBag()
bag.put( "ships", new StringTemplateGroup( ... ) );
bag.put( "html", new StringTemplateGroup( ... ) );

client = new StringTemplateGroup( ... );
client.setSuperGroup( bag );

And then the client templates can access templates from one or the  
other with some kind of absolute syntax $/html.anchor()$ perhaps?.

Or am I missing something in the API?

On 21 Dec 2008, at 10:05 am, Mike Pagel wrote:

> Thanks for your explanation. But even if I set aside the class/method
> analogy: how would I organize my templates then? From what you wrote I
> basically see that typically a template calls other templates within  
> the
> same group. So how can I reuse a template for instance across  
> different
> projects? Copy and paste it into the other project's template group
> file? Merge this and the other project's group files?
>
> You are basically saying that all templates reside in a single group
> with inheritance being a feature to be used mainly for retargeting,  
> but
> that's not practical for large scale projects. Other template engines
> like XPAND (open architectureware), T4 from MS DSL Tools, MD Workbench
> from Sodius, JET, ... *all* support splitting up your template project
> into trees of template files that can call each into each other. This
> way a template that knows how to serialize an attribute to something
> like "int i" can be used for class attributes as well as for method
> arguments, without the whole template zoo residing in a single group.
>
> Another example: if a want to create the three elements of an MVP  
> style
> application I will create at least three files, one for the business
> object model, one for the view and one for the presenter. Would I  
> create
> three different template groups, one for each file? But how do those
> groups then share common templates? By (single) inheritance? Or  
> would I
> have to put all templates into a single group? That's gonna be some  
> file!
>
> Is it really true that ST assumes most of the templates for a given
> project sit inside a single group?
>
> Mike
>
>
>
> Loring Craymer schrieb:
>> Your understanding is flawed--template groups are not classes, nor  
>> are
>> templates methods.  Treating them as such is likely to cause you
>> grief.  Think rather that template groups are a convenience for
>> argument checking against a template interface.  That way, changing
>> template groups makes it possible to switch from, say, generating  
>> Java
>> code to C# just by switching template groups.  Template groups are a
>> mechanism for retargeting.  Switching individual template groups  
>> within
>> an application while leaving others unchanged is not a common usage
>> pattern.
>>
>> Instead of thinking of templates as methods, take a
>> simpler view:  arguments fill "holes" in templates and the arguments
>> should be thought of in "instantiated" form.  Thinking of arguments  
>> as
>> dynamically invoked methods misses an important level of abstraction:
>> argument evaluation is independent of template evaluation and is
>> side-effect free.  [It is possible to implement side-effects as the
>> result of evaluation through reflection, but the results are
>> unpredictable.  Do not do this!]
>>
>> It is possible to invoke other
>> templates in the same group from within a template, but you should  
>> see
>> this as a macro invocation, and the facility as a convenience to  
>> allow
>> factoring.  Almost always, the invoked template is local to the
>> template group (not declared in the interface).  Such invocations  
>> tend
>> to be uncommon.
>>
>> --Loring
>>
>>
>>
>>
>> ----- Original Message ----
>>
>>> From: Mike Pagel <mike at mpagel.de>
>>> To: antlr-interest at antlr.org
>>> Sent: Saturday, December 20, 2008 7:45:01 AM
>>> Subject: [antlr-interest] Organization of complex template  
>>> structures
>>>
>>> Hi there,
>>>
>>> I am wondering how to best go about structuring complex sets of  
>>> string
>>> templates. As I understand the current mechanisms, a template  
>>> group is
>>> pretty much a class with its templates being the class methods.  
>>> You can
>>> build inheritance structures between groups and thereby overriding
>>> templates (the methods) and call super group (class) templates.
>>>
>>> This allows to build up some structure in terms of reusing basic
>>> templates and if required specialize certain pieces. But in the  
>>> end, you
>>> always call a template (method) that is part of or being inherited  
>>> by a
>>> specific leaf template group (class). Once the thread of control is
>>> within a template group there is no means to call templates in other
>>> groups, except for the groups which belong to inheritance line of  
>>> the
>>> leaf group (if I'm not missing anything).
>>>
>>> So far I find this limiting, e.g. if my model describes (Java)  
>>> classes
>>> and I want to generate the class code. Then my leaf template group  
>>> may
>>> be a "class.stg" with all kinds of templates like  
>>> "generateMethods()"
>>> and "generateAttributes()". The implementation of those template now
>>> should invoke templates from a group "Methods.stg" and another group
>>> "Attributes.stg". (This example may not be pressing the issue but  
>>> it's
>>> easy to follow.)
>>>
>>> Now I cannot derive "Class.stg" from both other groups, nor can I
>>> somehow call into these groups (like calling static members  
>>> functions of
>>> another class in code). What would be a good way to express this  
>>> with
>>> the current mechanisms or is there actually a limitation?
>>>
>>> Thanks a lot,
>>> Mike
>>>
>>> List: http://www.antlr.org/mailman/listinfo/antlr-interest
>>> Unsubscribe:
>>> http://www.antlr.org/mailman/options/antlr-interest/your-email-address
>>>
>>
>>
>>
>>
>>
>> List: http://www.antlr.org/mailman/listinfo/antlr-interest
>> Unsubscribe: http://www.antlr.org/mailman/options/antlr-interest/your-email-address
>>
>
> List: http://www.antlr.org/mailman/listinfo/antlr-interest
> Unsubscribe: http://www.antlr.org/mailman/options/antlr-interest/your-email-address



More information about the antlr-interest mailing list