Lambda/method

1,130 views
Skip to first unread message

Dharmesh Patel

unread,
Dec 6, 2010, 2:21:39 PM12/6/10
to mustache.java
I couldn't figure out how to implement/use "lamda" using
mustache.java.


Info about lamda
=====
http://mustache.github.com/mustache.5.html

When the value is a callable object, such as a function or lambda, the
object will be invoked and passed the block of text. The text passed
is the literal block, unrendered. {{tags}} will not have been expanded
- the lambda should do that on its own. In this way you can implement
filters or caching.

Template:

{{#wrapped}}
{{name}} is awesome.
{{/wrapped}}

Hash:

{
"name": "Willy",
"wrapped": function() {
return function(text) {
return "<b>" + render(text) + "</b>"
}
}
}

Output:

<b>Willy is awesome.</b>

Sam Pullara

unread,
Dec 6, 2010, 2:32:58 PM12/6/10
to mustac...@googlegroups.com
This isn't currently implemented. It wasn't clear to me the best way to do this in Java and how you would go about expanding the inline text once you got it. Should be pretty easy to implement though if we can agree on how that would work. I'll take a look at it today to see if it will be trivial or not.

Straw man proposal would be that your return value must implement com.google.collections.base.Function<String, String> -- should we allow an easy way for you to then ask Mustache.java to interpret the contents after you have manipulated it? Should it always manipulate it after you return the new one? This would imply an additional compile step for every lambda invocation which would be very expensive. Perhaps add an interpreter to the system to make that more feasible?

Sam

Dharmesh Patel

unread,
Dec 6, 2010, 3:24:58 PM12/6/10
to mustac...@googlegroups.com

Sent from my iPhone

Mohan D

unread,
Dec 6, 2010, 7:44:00 PM12/6/10
to mustache.java
I think it makes sense to call this function with a completely
processed text and let this function act on it. Processing the
template after the function might open to the door to an alternative
mechanism to partials. Processing the template after the function call
seems to complicate the process (understanding and performance). Does
it make sense to define this as a function that can decorate a
processed template?

Sam Pullara

unread,
Dec 6, 2010, 7:46:19 PM12/6/10
to mustac...@googlegroups.com
That would certainly be enough for caching, translation, alternate encoding (I've wanted this for XML attributes vs CDATA), 'safe' processing, etc.

Sam

Sam

unread,
Dec 7, 2010, 2:35:27 PM12/7/10
to mustache.java
Thinking about it a bit more I realized that you couldn't do caching
without the original. Thought of a bit more unwieldy solution using an
interface like this one:

void execute(Reader r, Writer w, Callable<Reader> c);

r - the raw text of the contents of the lambda
w - output for the result
c - execute the contents and give a Reader with the result

Kind of unwieldy. Will keep thinking...

Sam

Sam

unread,
Dec 12, 2010, 3:17:49 PM12/12/10
to mustache.java
After looking at what would be the least disruptive thing to do, I
decided to try something simple first. As of change dad987b you can
now return a Function<String, String> for a {{#variable}} and this is
what will happen:

1. The enclosed text is evaluated and captured
2. Your function is called passing in the resulting text string
3. The return value of the function replaces the contents of the
{{#function}}.

There is a simple test called testSimpleLambda that shows the trivial
case of transforming one result into another:

{{#translate}}Hello{{/translate}}
{{#translate}}{{#translate}}Hello{{/translate}}{{/translate}}

becomes:

Hola
Hello

When translate lambda is defined as:

Function<String, String> translate = new Function<String,
String>() {
@Override
public String apply(String input) {
if (input.equals("Hello")) {
return "Hola";
} if (input.equals("Hola")) {
return "Hello";
}
return null;
}
};

This does introduce a new dependency on Guava. That might be overkill
for this case. Maybe I should just have my own Function interface? Too
bad I can't "extend interface if class is on the classpath". It is
possible to return other types from the Function as null is converted
to empty string and the results of the Function are evaluated with
String.valueOf() if it makes more sense to return another type.

Sam
Reply all
Reply to author
Forward
0 new messages