[stringtemplate-interest] On Pragmatism Violating Purity For The Win (was: ST interface: canonical name, and null vs missing vs empty vs nonexistent)
Joseph Grace
ockham at gmail.com
Sun Oct 18 08:39:20 PDT 2009
*Zenaan Harkness* wrote at *Sat Oct 17 19:16:09 PDT 2009:**
>+1 for Template.
Yes.
>> Penny 2. Interfacing with Principle of Generous Acceptance
>Ack.
>Nice concept/ writeup. Thanks for sharing.
Thank you.
>> NB: "if.true" (boolean) is defined relative to the host language (not to>> ST), which can vary in meaning w/r/t whether "" is false or not in the host>> language. So the host language (I would say) should be the determining>> factor of the "native" semantics for boolean in ST for ease of use with each>> and every host language. In other words, ST adopts the host language T/F>> semantics for native least astonishment, and ease of use.>
>That's good for the newcomer, but not so good for the system and library
>builders.
>
>Java's awt lib illustrates my point, where 'pixel perfect' layouts [...]
I agree with your concern in general but not in this case so much.
Yes, this feature would be more for language impedance matching, and
not so much for large system building. As a complement to the system
building approach, "if.true" would provide a language-relative
solution to boolean, to perfectly match the host language's
interpretation of TRUE/FALSE. System builders could avoid it like the
plague (as its optional), but it could still cover the bases for
others. Since it's just one feature with many if.* duplicates, I
don't think the AWT example applies in this case (though it would in
more complex cases). There's no necessity to use "if.true", and it's
not intertwined with a bunch of other features. "if.true" would be
independent and optional, just one isolated feature. System builders
would be unaffected by this feature unless they choose to use it.
I prefer to think of "if.true" as getting the best of both worlds:
absolute definitions (predefined, for robust systems) and relative
(impedance matched to the host language, for lightweight, seamless
solutions). In some (many?) cases, if.true would duplicate one of the
other if.*, so it may only provide duplicate functionality in some
languages, but it would often be welcome where it does provide
specific semantics for its seamless use and transparent debugging.
And it would always respect the host language interpretation of
TRUE/FALSE, so that TRUE in the language would always be TRUE in the
StringTemplate (fewer surprises, lower learning curve, less debugging,
reliable and unambiguous host language programming).
I agree that the absolute if.*'s should be well designed for system
building, but I think if.true complements them even if it's just for quicky,
lightweight, and language specific application(s).
>Regarding per-host-language "customizations" however, unless presented
>with an example for which we cannot resolve or otherwise handle
>'comfortably' and 'easily' using 'strictly-standard' ST semantics/
>syntax, then let's stick to the high ground as long as possible.
For the sake of discussion... taking the low-ground! :-)
I see three questions with the if.* syntax and hook(s):
1. grammar: would "if.*" syntax and customizability be a reasonable
evolution for the StringTemplate language?
Since noone's complaining (yet?), I am supposing "if.*" is viable
grammar-wise.
2. philosophy: would Ter be OK with it? Is opening Pandora's Box in a very
focused way acceptable (even though it could be abused to Turing
Completion)? StringTemplate is his baby, and he might have to rewrite _all_
his papers on StringTemplate! ;-) Seriously, the Pandora's Box nature of the
hook puts a twist on the language and its use. It may open many doors, but
it Ter needs to be happy with the approach going forward.
Only Ter knows for sure. IMO, it could provide an elegant solution to making
StringTemplate flexible but doing so in a way that is very explicitly for a
specific, well-defined, limited use: Gentleman's Agreement if you will. Even
though it could be abused, it wouldn't be the language's or language
designer's fault. Also, abuses would be obvious just by looking at the
if.hook implementation by any StringTemplate coder. Use at your own risk, as
the saying goes.
3. Pragmatism & Purity: does this feature buy StringTemplate any new value
or use cases (or potentially expand the user base :-)?
A. The first use case I have in mind is the "escape valve" use case. I know
in corporate programming (I've been in this situation myself, and I'm sure
many of you have as well), a programmer may _know_ something will work
exceptionally well, but it's NIH (Not Invented Here). The manager and/or
project leads are all very (and when I say "very", I mean pathologically)
averse to change, risk, the unknown --- especially anything which may lead
down a proverbial rabbit hole with nothing to show for it but lost schedule.
They neither listen nor trust, and come up with _any_ excuse to shoot stuff
down. The escape valve preempts their "rabbit hole" attacks with an
all-encompassing "Not a problem. Pragmatism Prevails. In worst case, we'll
just 'if.*' our way to a solution (and out of any rabbit hole, real or
imagined)!"
StringTemplate's strength, purity & strict separation of concerns, could be
perceived as one such rabbit hole.
To get in the door, it's hard enough, but as a programmer in a "rabbit hole"
catch-22, I could always use the "escape valve" of the external "if.*" hook
to let my manager/lead _know_ without any hedging at all that we always
maintain a hook to do what we need. Then the risk is only the value of
StringTemplate relative to the usually deplorable status quo (no longer the
risk of rabbit hole'ing the schedule). The blind alley is no longer so much
a concern, and StringTemplate becomes a viable option where it may be needed
desperately (stick-in-the-mud engineering teams).
"if.*" anyone?
B. The other use case I think of is for legacy systems (or perhaps new,
unforeseen languages) where the escape valve is purposely abused, but
provides some unforeseeable advantage for a specific project or language.
Again, it's an "escape valve" example, but in this case providing a hook to
use StringTemplate against the grain. In some ways, this case is like above,
except the escape valve has been put into practice. Perhaps there are some
creative ways to use StringTemplate that are unforeseen, or some languages
that could benefit if flexibility were allowed (even if frowned upon).
Perhaps this hook could be implemented explicitly, e.g., "hook.*",
"CaptainHook.*" or "PandorasBox.*" ;-). That would make it an "explicit"
violation of separation of concerns, but at least then a switch could be
turned on/off disabling all such escapes. A localized leak of you will.
OTOH, the gentleman's agreement approach of hiding such a hook in "if.*"
(even though it would be a Pandora's Box) seems like an elegant solution
less inviting of trouble. Perhaps more in taste with Ter's papers, so he
doesn't have to fully revise them to totally reverse his claims about
purity. ;-)
In both cases, pragmatism prevails but in either a localized, gentleman's
agreement way (if.*), or a very explicit "Use At Your Own Risk" way
(hook.*).
"hook.*" anyone?
C. Hmm, just occurs to me (again, not sure of use case, but here goes), the
if.hook would allow for render time computation (instead of the usual load
time computation via t.add(...)). This could be useful for touchy debugging
(e.g., print the time when the render happened, to coordinate with other
aspects of the system or see any hangups in the rendering). It could also
dovetail better with some render-time only systems, making StringTemplate a
possibility where it never was before. Compute on demand >> compute
everything up-front.
"render.*" anyone?
D. Going further with render.*, "stream.*" could also cut down on
unnecessary computation by allowing a hook for generating data indefinitely,
i.e., render by stream (instead of by add(...) frontloading). "if.stream"
could stream results into the render process so that infinite streams could
be rendered. Again, this hook could be abused (Pandora's Box) but the
express intention would be clear: streaming data only. stream.* would focus
on potentially infinite streaming computation, i.e., _only_ for computation
not available at time of load via t.add(...). Is _this_ feature a useful
feature, application for StringTemplate? Perhaps streaming could open a few
more doors for StringTemplate?
"if.stream" anyone?
E. The render.* hook also provides a mechanism to dovetail StringTemplate
into existing systems. All existing systems can be thought of as render time
solutions. Worst case to dovetail StringTemplate into such a system, you can
put the entire legacy system in a "render.MyLegacySystem" hook. Tada! You're
now using StringTemplate (not in the way intended, but at least it's there).
So instead of having to redesign everything from scratch for legacy
system(s), StringTemplate could segue its way into use. Then one could
slowly migrate a legacy system from legacy -> StringTemplate piecemeal
without ever guaranteeing it will fully convert. Less and less work done at
render time, more and more work done at load time. Perhaps this entire
approach would comfort and ease many projects (especially large ones) to a
pure style of Template rendering, without having to figure out up-front
whether the pure approach would even work for everything. As long as it
works for -something-, the legacy project(s) could benefit from
StringTemplate.
"render.*" anyone?
I have no concrete use case(s), but I believe the concepts of Limited
Laissez-Faire (Pandoras Box) and render time computing could open some more
doors for StringTemplate. "if.*" (and its Pandoras Box Partners) could
provide:
a. Domain specific language/library impedance matching and customization
("if.*" boolean and beyond). [Gentleman's Agreement]
b. General purpose escape valve for backdoor computation ("if.*").
[Pandora's Box via Gentleman's Agreement ;-]
c. Render time hook ("render.*"). [Gentleman's Agreement]
d. Streaming hook ("if.stream"). [Gentleman's Agreement]
e. Enterprise applications ("render.*" For The Win!-). [App Migration:
Piecemeal Purity]
I guess those are largely theoretical use cases, but they do come from
experience and contain some grains of truth. "b" is really the endgame for
"B" (above): a provision for desperate measures for whatever reason, so that
StringTemplate can be used in impure situations without hitting a dead-end
(rabbit-hole'ing), alleviating the purity requirement without diminishing
the purity claim or design (via Gentleman's Agreement). Pragmatism Persists
while Purity Prevails.
"e" is more of the same but even more so, as the application is merely
trying to reach out for better purity, with no guarantee it will ever get
there.
So those are my theoretical use cases where with a few hooks into the
language, a lot of doors could open for StringTemplates where possibly
Pragmatism Violates Purity For The Win.
Apologies for the length, and expanding the discussion in an unforeseen way.
Ducking :-),
= Joe =
*
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.antlr.org/pipermail/stringtemplate-interest/attachments/20091018/60e755f0/attachment-0001.html
More information about the stringtemplate-interest
mailing list