Now, TRL is itself a recent addition to the NetKernel toolkit and the little sister of XRL - XML Recursion Language. In retrospect it was a missing child, for with Freemarker + TRL for text and XSLT + XRL for xml those two formats (which will both be around for a long time to come) are now pretty well covered.
No idea what a future (?) JSLT and JRL (with the J for JSON) will look like, but the format has great momentum and at some point the need for both tools will arise.
Little sisters often take the lead (mine provided my schoolbooks with neat covers long before I could cut straight with scissors ... and she reminds me of that until this very day) and TRL is no exception. Last week asynchronity was added to it. XRL will no doubt follow soon.
What does that mean ? Well, take this simple example :
<sequence>
<request assignment="response">
<identifier>active:trl</identifier>
<argument name="template">
<literal type="string">
<![CDATA[
Hello ${
<request>
<identifier>active:groovy</identifier>
<argument name="operator">
<literal type="string">
import org.netkernel.layer0.nkf.INKFResponse;
sleep(1000);
response = context.createResponseFrom("Tom");
response.setExpiry(INKFResponse.EXPIRY_ALWAYS);
</literal>
</argument>
</request>
} ${
<request>
<identifier>active:groovy</identifier>
<argument name="operator">
<literal type="string">
import org.netkernel.layer0.nkf.INKFResponse;
sleep(1000);
response = context.createResponseFrom("Geudens");
response.setExpiry(INKFResponse.EXPIRY_ALWAYS);
</literal>
</argument>
</request>
}
]]>
</literal>
</argument>
</request>
</sequence>
You can execute this in the Scripting Playpen (as DPML obviously). By the way, the <![CDATA[ ]]> is needed in order to put XML inside a string literal without having to escape it (thanks to Peter Rodgers for pointing that out).
The example itself doesn't do a lot, but time it with the Visualizer. You'll get something like 2010 ms. Which is to be expected with the two sleeps that are executed synchronously.
Now, try this :
<sequence>
<request assignment="response">
<identifier>active:trl</identifier>
<argument name="template">
<literal type="string">
<![CDATA[
Hello $a{
<request>
<identifier>active:groovy</identifier>
<argument name="operator">
<literal type="string">
import org.netkernel.layer0.nkf.INKFResponse;
sleep(1000);
response = context.createResponseFrom("Tom");
response.setExpiry(INKFResponse.EXPIRY_ALWAYS);
</literal>
</argument>
</request>
} $a{
<request>
<identifier>active:groovy</identifier>
<argument name="operator">
<literal type="string">
import org.netkernel.layer0.nkf.INKFResponse;
sleep(1000);
response = context.createResponseFrom("Geudens");
response.setExpiry(INKFResponse.EXPIRY_ALWAYS);
</literal>
</argument>
</request>
}
]]>
</literal>
</argument>
</request>
</sequence>
Time it again. You should get something like 1010 ms. We just halved execution time! The tradeoff - always be aware of those - is an extra thread. Still impressive. Go play with it! Try some recursion (a recursive example would have made the above completely unreadable).
To finish this entry ... it has been suggested that if we - humans - would have had an even number of digits on each hand/foot, we might have invented binary (and thus started the digital age) a lot sooner.