antlr / stringtemplate4

StringTemplate 4
http://www.stringtemplate.org
Other
955 stars 231 forks source link

better (monadic) list manipulation #143

Open Groostav opened 8 years ago

Groostav commented 8 years ago

as a user of string template, I would like a larger set of ~monadic operations on multi-value attributes, so that I am able to easily template strings of list form

I was rather annoyed to find out that if I had a POJO like this:

class Whatever{
  @Nullable Integer first;
  @Nullable Double second;
  @Nullable String third;
}

and I wanted String Template to generate something like

{first: 1 separator second: 2.345 separator third: six-seven}

(for the obviously corresponding object),

but simply omitting the separator and value for any missing field.

eg, second was null:

{first: 1 separator third: six-seven}

I'm actually left to using a switch:

{<\\>
<if(first)>first: <first><if(second || third)> separator <endif><endif><\\>
<if(second)>second: <second><if(third)> separator <endif><endif><\\>
<if(third)>third: <third><endif><\\>
}

which suffers from a nasty (quadratic?) length-complexity. In other words as I add more fields to my object, the string template requires quadratically more text.

I've spent the last hour attempting to solve this with maps and anonymous templates, the closest I've gotten is

<[first, second, third], ["first", "second", "third"]:{value, name|<\\>
<if(value)><name>: <value><endif>}; separator=" separator "><\\>

but, in the case where second is null, this gives me

{ first: 1 separator separator third: six-seven }

Looking at this from a monadic standpoint --because I remember from your book that you guys are huge fans of functional programming-- I think this has to do with the fact that the mapping and anonymous template schemes dont quite provide for a flatmap --which would give me the base tool I need to get this done.

That said, implementing a fold and/or filter would be very helpful too.

Further, in that particular example I'd like to switch from column-major to row-major.

So the two features I want are:

<[first, "first"], [second, "second"], [third, "third"]:{value, name |<\\>
name: value; if(value); orientation=inner<\\>
}

In general: perhalps a keyword between the colon and the opening curley to specify other monadic operations, (with the 'implicit' operation being map?)

then we can do nifty things like

<[first, "first"], [secon, "second"], [third, "third"]<\\>
:orientation(inner)<\\>
:filter{value, name|name}<\\>
:{value, name|<name>: <value>; separator=" separator "}