[stringtemplate-interest] List comprehensions Was Re: Working with filtered list

Colin Bean ccbean at gmail.com
Wed Jun 27 11:32:03 PDT 2007


Hi John,

I agree, python-like list comprehensions would be a very powerful
feature (I've also wondered about this as a way to filter within ST,
so I'm glad you brought it up!)

I like your idea of:
$items if it.isFancy :decorate(it)$

It seems to me the most minimal and closest to existing ST syntax.
I'd be fine with Python-style syntax, but that's because I'm already a
Python programmer -- could see how other people could take issue with
this.

Also, correct me if I'm wrong, but the main ability a comprehension
gives you (aside from nicer code) is the ability to access an $i$
value for the filtered attributes only -- as opposed to an existing
expression like:

$items:{
      $if(it.isSmart)$ $it$ $endif$
}$

Would a comprehension allow you to do anything else that you can't currently do?

Anyway, thanks for the thoughts!
Colin

On 6/26/07, John Snyders <jjsnyders at rcn.com> wrote:
> The key thing here is that you want the iteration variable i to count
> the filtered items not the original items. In both the templates below
> $i$ is going to count the original items.
>
> What you need is to filter first and then invoke the template that will
> optionally count the filtered items.
>
> But this can't be done with string template. A template once invoked
> always returns a string never a list and so once you have filtered the
> list it is a string and can't be iterated over any more.
>
> The solution, as you found, is to do the filtering in the program.
>
> In a recent message on indexing lists
> (http://www.antlr.org:8080/pipermail/stringtemplate-interest/2007-June/001090.html)
> I proposed the slice function. I wrote: "I think the request for
> indexing is mostly about wanting to iterate over a list differently.
> Just the first five, all but the last 2, every third one, etc.". The
> proposed slice function doesn't even handle the last example (every
> third one) and I specifically did not include other examples such as
> just the smart ones although that is a reasonable thing to want to do.
>
> What would be really powerful is the Python list comprehension
> functionality. The question is does it break separation? StringTemplate
> already has the ability to construct new literal lists. I mention some
> problems with it here
> (http://hardlikesoftware.com/weblog/2007/06/01/thoughts-on-stringtemplate-part-1/)
> but adding list comprehensions like in Python could make it even better.
> (see this for a quick intro to list comprehensions in Python:
> http://docs.python.org/tut/node7.html#SECTION007140000000000000000)
>
> Here is what it might look like
> $[x for x in data if x.IsSmart]:{ $it.CustomerName$ }$
>
> No comparison expressions have been introduced. The program is still
> responsible for implementing the logic by setting the IsSmart property.
> It is just a combination of list iteration, if evaluation (the same if
> already supported), and list construction.
>
> But the syntax is very Python. Is there something that may feel more ST
> like.
>
> List construction already allows a comma separated list of expressions.
> So something like this is possible:
> $[items, decorate("foo"), "bar"]: { x | ($x$)};separator="; "$
>
> If it allowed templatesExpresson (this includes the syntax for
> iterating) then something like this would be allowed:
> $[items:decorate(it), decorate("foo"), "bar"]: { x | ($x$)};separator="; "$
> What this says is for each item in attribute items call the decorate
> template and add the string returned to the list being constructed then
> call the decorate template with string argument foo and add the result
> to the list then add plain old "bar" to the list. With the list just
> constructed iterate over it wrapping each item in ( ) and putting a "; "
> separator between each one.
>
> By wrapping the iteration syntax in $[ ]$ it says rather than
> concatenate these into a string put them in a list.
>
> Now this syntax may have some problems with figuring out where commas go
> if parallel lists or alternating lists are allowed. I'm not sure what to
> do about that. I already find it unfair that I can't combine parallel
> lists with alternating lists.
>
> All that would be needed to have the power of Python list comprehensions
> is fitting in the "if" expression. Perhaps:
> $items if it.isFancy :decorate(it)$
> or
> $items : { x | x.isFancy | Fancy: $x$. }$
>
> On the other hand I wonder if the Python list comprehension syntax is
> more power full.
>
> I'm sure there are more details to figure out.
>
> Thats if for now. What do you think would list comprehensions be helpful
> for StringTemplate?
> -John
>
>
> Grzegorz Danowski wrote:
> >
> > Hi,
> >
> > I would like to filter list of customers and simultanously if output
> > list contains more customers then one I'd like to add sequence number.
> >
> > I have found template that filter data:
> >
> > StringTemplate template = new StringTemplate("$data:{" +
> >
> > "$if(it.IsSmart)$$it.CustomerName$$endif$}$");
> >
> > And have found template that add sequence number if customers number
> > is greater then one:
> >
> > StringTemplate template = new StringTemplate(
> >
> > "$if(rest(data))$$data:{$i$. $it.CustomerName$}$" +
> >
> > "$else$$data.CustomerName$$endif$");
> >
> > But I don't know how connect both functionalities in one tempate.
> >
> > Regards,
> >
> > Gregory
> >
> > ------------------------------------------------------------------------
> >
> > _______________________________________________
> > 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