[stringtemplate-interest] template expressiveness

Nate misc at n4te.com
Fri May 11 11:00:19 PDT 2007


Terence Parr wrote:
> On May 10, 2007, at 5:24 PM, Nate wrote:
>
>   
>> Terence Parr wrote:
>>     
>>>> B. Would index access to lists break separation? Eg...
>>>> $tests[0].name$
>>>> $tests[1].name$
>>>>
>>>>         
>>> yep because it is like calling a function with an argument from  
>>> the  template, not that there aren't similar things.  Even  
>>> referencing an  attribute requires that I invoke toString, the  
>>> difference is that  there are no attributes or arguments going in.
>>>
>>>
>>>       
>>>> [0] can be done with first(), but getting the nth element is   
>>>> impossible otherwise.
>>>>
>>>>         
>>>   on purpose I am afraid.
>>>
>>>       
>> I disagree. Why is getting the first or last element any different  
>> than getting the second? This is template logic and doesn't break  
>> separation. IMO, it should be possible to index lists (stuff[1] and  
>> stuff[-1]) and also to get sublists (stuff[2..5] and stuff[3..-2]).
>>     
>
> picking element n from a list is very different than picking stuff 
> [1].  I don't need an arg on stuff[1] as it's first(stuff).
>   
Lists are zero-based so stuff[1] would pick the second one.

> So you are in favor of allowing randomfunction(randomarg).  That's  
> fine.  Plenty of other turing complete template engines if you'd  
> prefer.  Note I've built many sites and I've not had a problem.
>   
I'm not suggesting calling any function with any argument. I'm 
suggesting allowing elements to be picked out of a list by index.

Are you even reading my messages? From your lack of capitalization in 
most of your responses, I assume you skim through emails and whip up 
quick replies.

I never asked for a turing complete template engine. Apparently, if 
someone suggests something you don't understand or don't agree with, 
then you tell them they must be using the wrong tool and should leave? I 
think I will take your advice. I have found it difficult to contribute. 
For example, it took about four emails to convey how formal argument 
checking is flawed. Even then, I'm not sure you actually understand the 
problem and I am skeptical that it will be fixed in a future version.

>> It isn't like calling a function with an argument. It only pulls an  
>> indexed value out of a list.
>>     
>
> Yes, but what about using stuff[i] where i is an attribute (stuff[32]  
> is probably useless)?  In that case you assume is an int.  What if  
> you change to a string with a char like '2-321'?
>   
stuff[i] gets element at index "i". If "i" is not an integer, an 
exception is thrown. Lists can only be indexed by integers, so where did 
you get the idea I was asking for randomfunction(randomarg)?

>> No matter how hard you try, you cannot make StringTemplate both  
>> useful AND impossible to break separation.
>>     
>
> Well i've made a few things that are grey area for usability, but  
> actually I think I can 'cause I have done useful things w/o opening  
> it up. ;)
>   
I can implement Map and invoke random code using an argument passed in 
from a template: line 425 of ASTExpr.java, ST v3.0. How much more open 
can you get?

Now, Map has many methods to implement and is quite a pain to go through 
just to misuse ST. This is an obvious misuse of the API, but isn't so 
bad that map access should be removed from templates. Map access is 
normally valid, since looking up a named value from a map is similiar to 
looking up a bean property from an object, just available map keys are 
not enforced as strictly.

>> Instead I feel the goal should be to provide a path for the user  
>> where they respect separation.
>>     
>
> If you want an engine that only encourages it in the doc, there are  
> plenty.
>   
As shown, ST is already one of those that only encourages it in the 
documentation. The difference is that in most other engines, breaking 
separation is easy. In ST it is harder. This is a good thing. The goal 
is to get the job done without breaking separation. I just don't see a 
need for it to be *impossible* to break separation. That is a very 
academic view and is just going to get in the way of getting the job done.

>> As I see ST now, it can do probably 70% of things well. 15% of  
>> things are awkward and 15% of things are impossible without  
>> refactoring the controller. ST lacks a lot of expressiveness and  
>> that really shows when it is used for HTML. For example,  
>> alternating table rows in ST doesn't work in the real world. Sure,  
>> in documentation you can show how templates can be applied in a  
>> round-robin fashion, but this requires duplicating the template  
>> that outputs the row. In a real application this is probably not a  
>> simple template, and I certainly don't want to copy and paste it  
>> just so I can alternate row colors!
>>     
>
> Really? No problem.  factor into more templates then pass arguments.   
> easy.  just like function calls right?
>   

As it is, I am required to have two *completely* separate templates that 
are identical, except they output different colored TR tags...
$stuff:row1(), row2()$

If ST could curry, then it would work...
$stuff:row(color="red"), row(color="blue")$

A potentially better solution...
$stuff:{
    <tr $if(i % 2)$style="color:red"$endif$><td>$it.name$</td></tr>
}$

Ideally, I should be able to fully manipulate attributes that did not 
come from the model. Eg, since the int "i" comes from the view, I'd like 
to be able to say "if (it % 3 == 1)". If "it" were to come from the 
model, then that should be invalid, since that would break separation.

Currently ST restricts template logic by applying the same constraints 
on template attributes as it does on model attributes. If the 
distinction could be made, it could open up an enormous amount of 
template expressiveness.

-Nate



More information about the stringtemplate-interest mailing list