<span class="Apple-style-span" style="font-family: Times; font-size: medium; "><b><div><span class="Apple-style-span" style="font-weight: normal;">First, a clarification. I finally found the canonical name for my "Principle of Generous Acceptance". It is the <a href="http://en.wikipedia.org/wiki/Robustness_Principle">Robustness Principle</a> (also "Postel's Principle"). (Apologies for not finding it on my previous search!)</span></div>
<div><span class="Apple-style-span" style="font-weight: normal;">However, I still prefer my phrasing of it <span class="Apple-style-span" style="font-family: Courier; font-size: 13px; font-weight: bold; ">"Be strict in what you generate, but generous in what you accept."</span></span></div>
<div><span class="Apple-style-span" style="font-weight: normal;"><br></span></div>Zenaan Harkness</b> wrote at <i>Sun Oct 18 18:22:26 PDT 2009:</i><p></p><ul></ul><pre>> If we added native.if, are there other operators you see</pre>
<pre>> being useful in the native.* library?</pre><pre>I am not looking to add operators other than "if.*" to the core language.</pre><pre>The ST philosophy is strict separation of concerns. Even the existing "if" is a violation of strict separation in that ST inspects an aspect of the model albeit in a very tidy way. The recognition of a second "if" is another step toward such pragmatism. I believe the "Robustness Principle" (strict in what you generate, generous in what you accept) explains why these "if.*" are so important even though (strictly speaking) they violate the purity of the language. Add "if.*" but only in a very controlled fashion, e.g., "if.null". I do not suggest ST be littered with operators and violations of model/view separation.</pre>
<pre>> Modifying ST into 'platform specific' variants is a significant</pre><pre>> change if it were undertaken.</pre><pre>That's not my intent or intended suggestion. The only supported compatibility variant as envisioned would be the one instruction, "native.if". The rest of the "native.*" namespace would be for user customizations (unsupported, Use At Your Own Risk).
> A native.* library would be good to think/ plan for in advance
> though, rather than one feature at a time, don't you think?
</pre><pre>I'm thinking of "native.*" more as opening the door to user extensions, not as a new part of the language. Mostly for ease of use, compatibility, and only a little bit of "Awaiting Further Developments" if you will, to see what happens from user extensions.</pre>
<pre>-=-</pre><pre>The basic existence "if" is a practical necessity, and has been shown largely "necessary and sufficient" for ST just not totally practical. The question becomes how to handle multiple "if"s in ST. I believe the answer is to recognize that "necessary and sufficient" is not necessarily sufficient! "Practical" is also important, and I think that's because of the "Robustness Principle", i.e., "generous in what you accept" as in making ST easy to use (without losing ST's strength and spirit of purity).</pre>
<pre>Hence adding multiple "if"s is practical, but how should it be handled? There's the rub.</pre><pre>I can see multiple options depending on how seriously one takes ease of use, "Robustness Principle", and attitude toward ease of adoption of ST (and how to go about it). Just looking at ST language merits (and not, e.g., a marketing campaign!), I see the options as follows:</pre>
<pre>1. Should ST add a single monolithic operator, "ifnull". Is that practical? What if there are other "if" operators that are desirable (as already mentioned on this list)?</pre><pre>2. Should ST then add a clean syntax for multiple "if.*" language independent operators? Is that practical? What if a common use case is to dovetail ST onto an existing system, in a native language, and the native language "if" is not found in ST? What if ease of use is compromised without native language friendly "if"?</pre>
<pre>3. Should ST then add a "native.if" which handles language native "if" but in a tidy, automatically flaggable (command line flag -> warning/errors), but built-in fashion? Does this increase language/legacy friendliness enough, or does "Robustness Principle" generosity suggest that users may have unforeseeable user-specific and domain specific needs beyond "native.if"?</pre>
<pre>4. Should ST then make "native.*" a generic hook for user-specific augmentation of the language to suit their specific needs? "native.if" would then be the exemplar (code template for "native.*" extensions) for users to build additional hooks. The hooks may be few and far between, or become shared. However, at least users would have power to augment ST specifically for their needs (impure or not). Now users can customize ST in a controlled fashion ("native.*" operators) using their language of choice for their application(s). Would "native.*" extensions be automatically portable across all ST users? Of course not, since "native.*" extensions would be language/application specific. Would "native.*" extensions be shareable at all? Yes, "native.*" extensions could be shared among ST users who share a common language/application (e.g., Ruby on Rails for Ruby ST --- if it existed!-). Is that desirable? I think so.</pre>
<pre>So those are the options as I see them. The big difference is philosophy about where ST is headed, and how to get there? Big steps or baby steps? I don't know, but I don't like monolithic design, and do like options.</pre>
<pre>To recap:</pre><pre>1. "ifnull" (one new keyword)</pre><pre>2. "if.null", "if.empty", et al. (syntax extensions for a few additional common ST use cases, tidy "if.*" extensibility)</pre>
<pre>3. above + "native.if" (above + language compatible "native.if" for native language compatibility use case)</pre><pre>4. above + "native.*" (above + user extensible syntax hook for open-ended user and application specific use cases)</pre>
<pre>IMO, these are all reasonable approaches.</pre><pre>I view #1 as a band-aid, old school (a la Bourne shell keywords) with little future extensibility other than adding more monolithic keywords. #1 adds a "fix" with low-risk to purity, and low potential.</pre>
<pre>I see #2 as more promising. It acknowledges there's a bit more to the issue ("Robustness Principle"'s Generous Acceptance and ease-of-use) than a single "ifnull" and explicitly leaves room for tidy "if.*" ST extensibility. #2 adds a more sophisticated fix with low-risk, and some future potential (through the "if.*" syntax).</pre>
<pre>I like #3's extensibility since it takes the extensibility syntax to a natural progression and adds a hint of native language compatibility, "native.if". #3 has #2's sophisticated fixes, and adds a compatibility feature for native languages. Philosophically, this could be considered risky (portability violation). OTOH, I believe the nod to native language compatibility is a big step forward in appreciating the importance of "Generous Acceptance" [Robustness Principle] and ease of use. In other words, even though purity prevails in ST, pragmatism has its place. The "native.if" would be that built-in for ST.</pre>
<pre>I like #4 the best, but it's the riskiest (biggest leap) since it would open the door to user extensibility. Is there any value in user extensibility, or it just a Pandora's Box? I think it's a logical extension and may have hidden value (unforeseen advantages). As I outlined in a previous post, providing full extensibility hooks is sometimes essential for political/mental acceptance of "foreign" technology, e.g., the NIH (Not Invented Here) Syndrome. As long as "necessity is the mother of invention", extensibility could lead to some very innovative uses for ST. To fully embrace "Generous Acceptance" [Robustness Principle], "native.*" and user extensibilty seems the next logical step when adding "if.*" and "native.if" to ST.</pre>
<pre>-=-</pre><pre>So that's how I see the "ifnull", "if.*", "native.if", and "native.*" conversation. It's been very thought-provoking. I feel some resistance by the experts (and maybe rightly so), but at least the options are under consideration.</pre>
<pre>I'm mostly interested in Ruby and am toying with taking Ter's Toy-ST and converting that to Ruby. I've been wondering how to get ST on Ruby for some time. I'm hoping Toy-ST is the path of least resistance.</pre>
<pre>I think it's important to give a nod to pragmatism, even when ST's core strength is purity. Perhaps it's even -more- important to nod to pragmatism since ST has such strong purity genetics. I think pragmatism has already gotten a boost in the discussion of abbreviating "StringTemplate" to "Template" (not to mention "ST").</pre>
<pre>IMO, ST has the genetics to be the king of the hill in templating, and Ter continues to improve on it with v4. The rub seems to be less about genetics and power, than about packaging and ease of adoption.</pre><pre>
I believe the biggest opportunity for ST to grow is to convert users with greater ease of use, ease of adoption. I believe ST's purity is a two-edged sword. Strict adherence to separation of concerns (model/view) keeps the ST language pure and valuable, but can make ST harder to adopt (and appear riskier to prospective users, tech leads, managers). I believe a few nods toward pragmatism with ("if.*") and user extensibility ("native.*") could alleviate some of those concerns.</pre>
<pre>Could these changes lead to wider ST adoption? Possibly, but perhaps that's just my wishful thinking. We all want ST to be successful. The question is how, not just from a purity of language standpoint, but also from an ease-of-use and safety of adoption standpoint. I think "Generous Acceptability" [Robustness Principle] could lead the way, and that's where I suggest extrapolating beyond the simple "ifnull".</pre>
<pre>Cheers,</pre><pre>= Joe =</pre><pre><br></pre></span>