<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/stylesheets/rss.css" type="text/css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Tom Moertel's Weblog: Category web development</title>
    <link>http://blog.moertel.com/articles/category/web-development</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Quality rants on programming theory and stuff geeks like</description>
    <item>
      <title>A bright future: security and modern type systems</title>
      <description>&lt;p&gt;The &lt;a href="http://it.slashdot.org/it/07/08/12/1550254.shtml"&gt;recent defacement of the United Nations web
site&lt;/a&gt; is a prime
example of why we programmers shouldn&amp;#8217;t trust ourselves to write
secure code &amp;#8211; at least not without our computers&amp;#8217; help.  The U.N. web
site, according to Slashdot&amp;#8217;s coverage of the incident, was defaced by
way of a common, well-known attack: &lt;a href="http://en.wikipedia.org/wiki/SQL_injection"&gt;&lt;span class="caps"&gt;SQL&lt;/span&gt;
injection&lt;/a&gt;.  What&amp;#8217;s
interesting is that programmers can render this attack harmless by
employing simple, readily available programming tools such as
placeholders and prepared statements.  Why, then, are so many web sites,
including the UN site apparently, still vulnerable?&lt;/p&gt;


	&lt;p&gt;Some say it&amp;#8217;s because the programmers of these sites are incompetent,
but that argument ignores that programmers are
human, while the security tools we give them offer meaningful
protection only if wielded with inhuman perfection.  Having the tools
to plug security holes, even if the tools are simple to use and
readily available, is not enough to ensure that every single security
hole will be identified, let alone plugged.  Even the most experienced
programmer can be expected to overlook a hole now and then.
Unfortunately, one hole is all it takes.&lt;/p&gt;


	&lt;p&gt;That&amp;#8217;s because security is not like other software-quality challenges:
its costs are fundamentally asymmetric.  For the attacker, the bad
guy, the challenge is to find just a single exploitable hole.  For
us, the good guys, the challenge is to achieve perfection: to plug
&lt;em&gt;all&lt;/em&gt; of the holes in our code, every single one.  That&amp;#8217;s because
attackers, unlike regular users, can be expected to probe our code
until they find a hole to exploit.&lt;/p&gt;


	&lt;p&gt;How then do we ensure that we have plugged every single hole in our
code?  Testing isn&amp;#8217;t sufficient: we can easily overlook holes
when writing tests &amp;#8211; a perfectly human error.  We could supplement
testing with code reviews, painstakingly searching for remaining holes
while enforcing the use of hole-preventing best practices, but reviews
are expensive and, again, subject to human error.  A better approach,
both less costly and more reliable, is to delegate this burden to our
computers, which can do the job correctly, every single time.&lt;/p&gt;


	&lt;p&gt;This kind of delegation is possible today with modern static type systems.
For example, in &lt;a href="http://blog.moertel.com/articles/2006/10/18/a-type-based-solution-to-the-strings-problem"&gt;A Type-Based Solution to the Strings
Problem&lt;/a&gt;,
I offered a tiny &amp;#8220;safe strings&amp;#8221; library for the &lt;a href="http://haskell.org/"&gt;Haskell programming
language&lt;/a&gt;.  The library takes advantage of
Haskell&amp;#8217;s powerful type system to detect unsafe string interactions at
compile time. If we faithfully build our code on top of the library, and our
code compiles without error, we can be assured that our code is
free &amp;#8211; completely free &amp;#8211; of &lt;span class="caps"&gt;SQL&lt;/span&gt;-injection (and &lt;a href="http://en.wikipedia.org/wiki/Cross-site_scripting"&gt;&lt;span class="caps"&gt;XSS&lt;/span&gt;&lt;/a&gt;) holes.&lt;/p&gt;


	&lt;p&gt;While this result is indeed quite beautiful, it certainly isn&amp;#8217;t novel.
Researchers have been proving interesting
properties via type systems for a long time.  As Oleg Kiselyov and Chung-chieh Shan pointed out in &lt;a href="http://blog.moertel.com/articles/2006/10/18/a-type-based-solution-to-the-strings-problem#comment-204"&gt;a comment on my earlier article&lt;/a&gt;, the foundational idea is over three decades old.&lt;/p&gt;


	&lt;p&gt;More recently, Kiselyov and Shan have extended the
idea to guarantee more-interesting properties using a trusted kernel and types that represent
&lt;a href="http://okmij.org/ftp/papers/lightweight-static-capabilities.pdf"&gt;lightweight static
capabilities&lt;/a&gt;.
The kernel, which is small enough to be reasoned about and formally
verified, carefully hands out capabilities to untrusted application
code.  The untrusted code, in turn, presents the capabilities back to
the kernel to invoke operations, which, thanks to the kernel&amp;#8217;s
trustworthiness, are guaranteed to be safe.  (My safe-string library
can be seen as a trivial implementation of this programming style.)&lt;/p&gt;


	&lt;p&gt;When static type systems are used in this way, they don&amp;#8217;t merely catch
typos and bugs that good testing would have caught as a matter of
course, but offer programmers guarantees that would have been
impractical to obtain any other way.&lt;sup&gt;&lt;a href="#un-sql-fn1"&gt;1&lt;/a&gt;&lt;/sup&gt; If
you consider security important, you might bear this fact in mind when
choosing languages for your next project.&lt;/p&gt;


	&lt;p&gt;Going further, the security benefits of rich static type systems are only now
starting to trickle into mainstream industry.  As libraries like &amp;#8220;safe
strings&amp;#8221; and idioms like static capabilities become more familiar and
get woven into future generations of development frameworks, we can
expect marked improvements in the security and robustness of our
applications.&lt;/p&gt;


	&lt;p&gt;In the not-too-distant future, perhaps, we might look
back in amazement at the days when important security properties were
neither free nor guaranteed but expensive and uncertain, underwritten
only by the heroic efforts of individual programmers, struggling
against impossible odds to achieve inhuman perfection.&lt;/p&gt;


	&lt;p&gt;Then again, it sure took garbage collection a long time to catch on.&lt;/p&gt;


&lt;hr/&gt;

&lt;div class="footnote"&gt;

	&lt;p&gt;&lt;a name="un-sql-fn1"&gt;1.&lt;/a&gt; How, for example, could you eliminate the
possibility of &lt;span class="caps"&gt;SQL&lt;/span&gt;-injection and &lt;span class="caps"&gt;XSS&lt;/span&gt; holes via testing?&lt;/p&gt;


	&lt;p&gt;I suppose you could do it if you worked at
it hard enough. You could augment your string data
structures with run-time information about what they represent:
&lt;em&gt;this string represents &lt;span class="caps"&gt;SQL&lt;/span&gt;, this string represents plain-old
text&lt;/em&gt;, and so on.  Then you could redefine your string operations
and template interpolation systems to assert that their string inputs
were compatible.  Of course, if these assertions ever failed, they
would do so only at run time, when it would be too late to do anything
but die rather ungracefully.  So you would be forced to augment your
code-coverage tools to ensure that every string-path was covered
during testing.  That way you could catch all potential run-time
string failures &amp;#8211; indicating holes &amp;#8211; during testing and eliminate the
holes (and the subsequent need to fail at run time) before you
deployed your application for real.&lt;/p&gt;


	&lt;p&gt;So, yes, you could do it.  But to do so would require you, in effect,
to write a crude, single-purpose type system that checks types at test
time.  That says something, doesn&amp;#8217;t it?&lt;/p&gt;


&lt;/div&gt;</description>
      <pubDate>Wed, 15 Aug 2007 16:07:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:fd522245-d8b7-4270-814d-5237a26bb0b9</guid>
      <author>Tom Moertel</author>
      <link>http://blog.moertel.com/articles/2007/08/15/a-bright-future-security-and-modern-type-systems</link>
      <category>programming</category>
      <category>web development</category>
      <category>security</category>
      <category>types</category>
      <category>security</category>
      <category>capabilities</category>
      <category>safestrings</category>
      <category>sqlinjection</category>
      <category>xss</category>
      <trackback:ping>http://blog.moertel.com/articles/trackback/524</trackback:ping>
    </item>
    <item>
      <title>Don't let password recovery keep you from protecting your users</title>
      <description>&lt;p&gt;In 2006&amp;#8217;s most-read article on my blog, &lt;em&gt;&lt;a href="http://blog.moertel.com/articles/2006/12/15/never-store-passwords-in-a-database"&gt;Never store passwords in
a
database!&lt;/a&gt;&lt;/em&gt;,
I urged web programmers, unsurprisingly, not to store passwords
in their user databases.  I tried to persuade them to salt and hash
the passwords instead: store the salts and hashes in the database and
throw the passwords away.  The article, posted shortly after the
Reddit blog announced the &lt;a href="http://web.archive.org/web/20070109023445/http%3A//reddit.com/blog/theft"&gt;theft of its unprotected user
database&lt;/a&gt;, generated buckets of comments.
Reading over them today, I noticed something that I had missed
earlier.&lt;/p&gt;


	&lt;p&gt;It seems that a decent slice of programmers think that switching
to a salted-and-hashed password scheme implies giving up the ability to
assist users who have forgotten their passwords.  If the
passwords are irretrievably hashed away, the programmers reason, there&amp;#8217;s no way
to recover forgotten passwords and email them to stranded users.
Hence those users are screwed.&lt;/p&gt;


	&lt;p&gt;And that wrinkle, it might seem, is a good reason not to switch to a
salted-and-hashed password scheme.&lt;/p&gt;


	&lt;p&gt;But that wrinkle turns out to be imaginary.  Not being able to recover
an account&amp;#8217;s password does not mean that you can&amp;#8217;t
recover the account itself.  The password, after all, is not the thing
of value; the account is.  And, as we shall see, we can recover
an account without knowing its password.&lt;/p&gt;


	&lt;p&gt;Recall that the primary benefit of using a hash is that it is a
one-way operation.  Once you salt and hash a password, there is no
practical way to retrieve it.  That&amp;#8217;s what protects it from would-be
attackers.  But that also means &lt;em&gt;you&lt;/em&gt; can&amp;#8217;t get at it, either.
Thus sending password reminders to people who have forgotten their
passwords is no longer an option.&lt;/p&gt;


	&lt;p&gt;How, then, can you help your stranded users?  One method is to send
them account-recovery tokens, which you can think of as one-time,
special-purpose passwords.  (This method is suitable only if you
require no stronger authentication than knowing that your site&amp;#8217;s users own
the email addresses they claim to own.  This is the case for most &amp;#8220;low
security&amp;#8221; sites such as Slashdot, Reddit, and Digg, as
well as most blogging systems.)&lt;/p&gt;


	&lt;p&gt;Here&amp;#8217;s how it works.  Say Joe has lost his password and can&amp;#8217;t log in
to your site. He clicks that button that says &amp;#8220;I&amp;#8217;ve lost my
password. Help me!&amp;#8221;  Now what?&lt;/p&gt;


	&lt;p&gt;Here&amp;#8217;s what you do:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Generate a big, random, unique token and stuff it into Joe&amp;#8217;s account record in the database.  Stuff the current date and time in there, too.&lt;/li&gt;
		&lt;li&gt;Send an email to Joe, but instead of enclosing his password (which you can&amp;#8217;t recover), tell Joe to click on the enclosed account-recovery link, which includes the random token: &lt;code&gt;http://example.com/recover-account?token=pCIqq1unxntVqc8XtCXg&lt;/code&gt;.&lt;/li&gt;
		&lt;li&gt;Joe receives the email and clicks on the link, which sends his token to your site.&lt;/li&gt;
		&lt;li&gt;Look up the token in the user database.  Is it there?
	&lt;ol&gt;
	&lt;li&gt;No? Render a screen that says, &amp;#8220;Sorry, bub, that token is no longer valid.&amp;#8221;  Stop.&lt;/li&gt;
		&lt;li&gt;Yes? Excellent. Grab the user record associated with the token.  (It will, of course, be Joe&amp;#8217;s record.)&lt;/li&gt;
	&lt;/ol&gt;
	&lt;/li&gt;
		&lt;li&gt;Is the date and time stamp on that record more than a few hours old?
	&lt;ol&gt;
	&lt;li&gt;Yes? Render that screen that says, &amp;#8220;Sorry, bub, that token is no longer valid.&amp;#8221; Stop.&lt;/li&gt;
		&lt;li&gt;No? Congratulations.  Joe has effectively authenticated himself via his email address.&lt;/li&gt;
	&lt;/ol&gt;
	&lt;/li&gt;
		&lt;li&gt;Render a confirmation screen that explains the following to Joe:
	&lt;ol&gt;
	&lt;li&gt;His account password is going to be reset to the following random string: &lt;strong&gt;ocZodbew&lt;/strong&gt;. (Generate a new random string each time.)&lt;/li&gt;
		&lt;li&gt;If he likes the password, great.  If not, he can use the change-password feature immediately after the password is reset.&lt;/li&gt;
		&lt;li&gt;If he understands the above and wants to continue, he should confirm by clicking the big &amp;#8220;Reset My Account Password&amp;#8221; button.&lt;/li&gt;
	&lt;/ol&gt;
	&lt;/li&gt;
		&lt;li&gt;Joe clicks the button.&lt;/li&gt;
		&lt;li&gt;You, in response, do the following:
	&lt;ol&gt;
	&lt;li&gt;Delete the recovery token from Joe&amp;#8217;s user record in the database. (This prevents somebody from using the old token to steal his account, should, for example, Joe&amp;#8217;s email get stolen.)&lt;/li&gt;
		&lt;li&gt;Replace Joe&amp;#8217;s old password with the new, randomly generated password from above.  (You will, of course, use the salted-and-hashed method and &lt;em&gt;not&lt;/em&gt; store the new password itself.)&lt;/li&gt;
		&lt;li&gt;Log Joe in.&lt;/li&gt;
		&lt;li&gt;Render a screen saying, &amp;#8220;Joe, please don&amp;#8217;t forget that your new password is &lt;strong&gt;ocZodbew&lt;/strong&gt;.  If you would like to change it, just visit Change My Password in your account preferences [provide a link].  Otherwise, you&amp;#8217;re logged in and ready to go.  Enjoy the site!&amp;#8221; &lt;/li&gt;
	&lt;/ol&gt;
	&lt;/li&gt;
		&lt;li&gt;And you&amp;#8217;re done.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;The code required to make it happen is shorter than the explanation
above.  It&amp;#8217;s one of those easier-done-than-said things.&lt;/p&gt;


	&lt;p&gt;So, if concerns about account recovery have been holding you
back from protecting your users&amp;#8217; passwords, you need hold back no
longer.  It&amp;#8217;s time to &amp;#8220;do&amp;#8221; your due diligence.&lt;/p&gt;


&lt;div class="update"&gt;

	&lt;p&gt;&lt;strong&gt;Update 2007-09-10:&lt;/strong&gt; I made clear that the account-recovery method I
describe above is suitable only for low-security sites where
a valid email address is sufficient to authenticate users.&lt;/p&gt;


&lt;/div&gt;</description>
      <pubDate>Fri, 09 Feb 2007 15:36:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:ddd87596-c734-4f36-996c-bc74a39e9dd3</guid>
      <author>Tom Moertel</author>
      <link>http://blog.moertel.com/articles/2007/02/09/dont-let-password-recovery-keep-you-from-protecting-your-users</link>
      <category>web development</category>
      <category>security</category>
      <category>security</category>
      <category>passwords</category>
      <category>salt</category>
      <category>hash</category>
      <category>database</category>
      <category>recovery</category>
      <category>risks</category>
      <trackback:ping>http://blog.moertel.com/articles/trackback/370</trackback:ping>
    </item>
    <item>
      <title>Never store passwords in a database!</title>
      <description>&lt;p&gt;Recently, the folks behind &lt;a href="http://reddit.com/"&gt;Reddit.com&lt;/a&gt; confessed
that &lt;a href="http://web.archive.org/web/20070109023445/http%3A//reddit.com/blog/theft"&gt;a backup copy of their database had been
stolen.&lt;/a&gt; Later, spez, one of the Reddit
developers, &lt;a href="http://reddit.com/info/usqe/comments/cuugl"&gt;confirmed&lt;/a&gt;
that the database contained password information for Reddit&amp;#8217;s users,
and that the information was stored as plain, unprotected text.
In other words, once the thief had the database, he had everyone&amp;#8217;s
passwords as well.&lt;/p&gt;


	&lt;p&gt;Had the folks at Reddit &lt;a href="http://en.wikipedia.org/wiki/Password_cracking#Salting"&gt;salted and
hashed&lt;/a&gt; the
passwords, the thief would now be in a very different situation.
Instead of holding all the keys to the kingdom, he would face the
prospect of a potentially expensive search for each and every user&amp;#8217;s
password he wanted to extract from the database.  The expense of the
search would likely have dissuaded him from making the attempt in
earnest, given how little exploitable value a Reddit account represents.  In
short, the passwords would have been secure, even though the database
had fallen into the thief&amp;#8217;s hands.&lt;/p&gt;


	&lt;p&gt;Why, then, didn&amp;#8217;t Reddit&amp;#8217;s programmers salt and hash the passwords
before storing them in their database?  Because, according to the
earlier post by spez, they wanted to be able to send forgotten
passwords to users via email.  It was a design decision: they
weighed the risks of having plain-as-day passwords in the database
against the convenience of being able to email users their forgotten
passwords and decided that, in the balance, convenience carried more
weight.  It&amp;#8217;s a decision they now regret.  (It&amp;#8217;s a doubly unfortunate
decision because &lt;a href="http://blog.moertel.com/articles/2007/02/09/dont-let-password-recovery-keep-you-from-protecting-your-users"&gt;you don&amp;#8217;t need to store passwords in your user database
in order to offer convenient account recovery&lt;/a&gt;.)&lt;/p&gt;


	&lt;p&gt;The reason I&amp;#8217;m writing about this event isn&amp;#8217;t to kick the
good folks at Reddit while they&amp;#8217;re down.  Rather, I&amp;#8217;m trying to make a point:&lt;/p&gt;


&lt;p style="padding-left: 2em; padding-right: 2em"&gt;&lt;strong&gt;If you are
storing passwords in a database, you are almost certainly making a
mistake.&lt;/strong&gt;&lt;/p&gt;

	&lt;p&gt;The guys at Reddit are known for being smart.  They thought they had a
good reason for storing passwords in their database.  They
were wrong.  If smart programmers can make this mistake, lots
of programmers can.  Do you think you have a good reason for storing
passwords in your database?  If so, you&amp;#8217;re probably wrong, too.&lt;/p&gt;


	&lt;p&gt;How can I be so sure?  Because, when it comes to web-app authentication,
cutting corners doesn&amp;#8217;t buy you anything. It doesn&amp;#8217;t save you coding time.
It doesn&amp;#8217;t give your users a better experience. All it does is weaken the security of your web application, needlessly putting your users, your employer, and yourself at  risk.&lt;/p&gt;


	&lt;p&gt;So please let me take this opportunity to ask if you
know of (or perhaps work on) any software systems that store passwords
as plain, unprotected text in a database.  If so, &lt;em&gt;fix your
software now&lt;/em&gt;:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Salt and hash each and every password (use an expensive hashing function such as bcrypt that was designed for password applications)&lt;/li&gt;
		&lt;li&gt;Store the salt and
hash &amp;#8211; not the password &amp;#8211; in your database. &lt;/li&gt;
		&lt;li&gt;Throw the password itself away.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;You&amp;#8217;ll be glad you did.&lt;/p&gt;


&lt;div class="update"&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Minor edits for clarity.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update 2007-02-13:&lt;/strong&gt; Salting and hashing does not get in the way of account recovery.  You do &lt;em&gt;not&lt;/em&gt; need to email users their forgotten passwords: there are other account-recovery options that are just as convenient but much more secure.  See &lt;a href="http://blog.moertel.com/articles/2007/02/09/dont-let-password-recovery-keep-you-from-protecting-your-users"&gt;Don&amp;#8217;t let password recovery keep you from protecting your users&lt;/a&gt; for more.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update 2007-10-03:&lt;/strong&gt; Revised text slightly to emphasize that there is no benefit to be had by implementing a weak password system, and therefore there is no reason &lt;em&gt;not&lt;/em&gt; to implement a secure system. Pointed more directly to bcrypt, too.
&lt;/div&gt;</description>
      <pubDate>Fri, 15 Dec 2006 13:25:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:547d5909-6007-46a3-ae22-ae1f8d348658</guid>
      <author>Tom Moertel</author>
      <link>http://blog.moertel.com/articles/2006/12/15/never-store-passwords-in-a-database</link>
      <category>web development</category>
      <category>security</category>
      <category>reddit</category>
      <category>security</category>
      <category>passwords</category>
      <category>salt</category>
      <category>hash</category>
      <trackback:ping>http://blog.moertel.com/articles/trackback/267</trackback:ping>
    </item>
    <item>
      <title>A type-based solution to the &amp;quot;strings problem&amp;quot;: a fitting end to XSS and SQL-injection holes?</title>
      <description>&lt;p&gt;Even skilled programmers have a hard time keeping their web
applications free of &lt;span class="caps"&gt;XSS&lt;/span&gt; and &lt;span class="caps"&gt;SQL&lt;/span&gt;-injection vulnerabilities.  And it
shows:  &lt;a href="http://portal.spidynamics.com/blogs/msutton/archive/2006/09/26/How-Prevalent-Are-SQL-Injection-Vulnerabilities_3F00_.aspx"&gt;a sobering portion of web sites are open to some scary security threats&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Why are so many sites vulnerable to these well-known holes?  Probably
because it&amp;#8217;s insanely hard for programmers to solve the fundamental
&amp;#8220;strings problem&amp;#8221; at the heart of these vulnerabilities. The problem
itself is easy to understand, but we humans aren&amp;#8217;t equipped to carry
out the solution.  Simply put, we just plain suck at keeping a
bazillion different strings straight in our heads, let alone
consistently and reliably rendering their interactions safe whenever they
cross paths in a modern web application.  It&amp;#8217;s easy to say, &amp;#8220;just
escape the little buggers,&amp;#8221; but it&amp;#8217;s hard to get it right, every single time.&lt;/p&gt;


	&lt;p&gt;Computers, on the other hand, are pretty good at keeping track of
details by the bucket-full. Wouldn&amp;#8217;t it be nice, then,
if our programming languages gave us the power to delegate this nasty &amp;#8220;strings
problem&amp;#8221; to our computers, which could then devote their unwavering mechanical precision to grinding the problem out of existence?  &lt;a href="http://weblog.raganwald.com/2006/03/ill-take-static-typing-for-800-alex.html" title="Raganwald: I'll take Static Typing for $800, Alex."&gt;Isn&amp;#8217;t that the kind of thing modern programming languages are supposed to be good at?&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;d like to think the answer to that question is a big, &lt;em&gt;you betcha&lt;/em&gt;.&lt;/p&gt;


	&lt;p&gt;So let&amp;#8217;s grab a modern programming language and solve the strings problem.&lt;/p&gt;


	&lt;h3&gt; Let&amp;#8217;s solve the strings problem in Haskell&lt;/h3&gt;


	&lt;p&gt;In this article, we will look at one way (among many) to solve the strings
problem: by adding Ruby-style string templates to Haskell.  These
templates support &amp;#8220;interpolation&amp;#8221; via the usual, convenient &lt;code&gt;#{var}&lt;/code&gt;
syntax, but here interpolation is type safe. Haskell&amp;#8217;s type system
will prevent us from inadvertently mixing incompatible string types,
and it will detect mistakes at compile time, before they can become
live &lt;span class="caps"&gt;XSS&lt;/span&gt; or &lt;span class="caps"&gt;SQL&lt;/span&gt;-injection holes.  Further, our solution will offer
us these benefits without making us jump through hoops or pay some
onerous syntax penalty.&lt;/p&gt;


	&lt;p&gt;To be more specific, the system offers the following benefits:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;It provides a string-management kernel that lets you create &amp;#8220;safe strings&amp;#8221; by &lt;em&gt;certifying&lt;/em&gt; a regular string as representing either text or a fragment of a known language.&lt;/li&gt;
		&lt;li&gt;It allows you to conveniently define new language types for any string-based language that you can provide an escaping rule for (e.g., &lt;span class="caps"&gt;XML&lt;/span&gt;, URLs, &lt;span class="caps"&gt;SQL&lt;/span&gt;, untrusted user input).&lt;/li&gt;
		&lt;li&gt;It provides compile-time syntactic sugar (via Template Haskell) that makes working with safe strings as convenient as working with string interpolation in languages like Ruby and Perl.&lt;/li&gt;
		&lt;li&gt;It catches and reports (at compile time) the following commonly made programming errors:
	&lt;ul&gt;
	&lt;li&gt;failing to escape a plain-old-text string before mixing it into a string that represents a language fragment&lt;/li&gt;
		&lt;li&gt;mixing strings that represent fragments of incompatible languages&lt;/li&gt;
		&lt;li&gt;mixing strings that represent fragments of compatible languages in an ambiguous way (the system will force you to disambiguate)&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;(This is a long one, so grab an espresso, lean back, and read on in
style.  Also, if you have a smoking jacket, you might want to get it now.)&lt;/p&gt;&lt;p&gt;Before I describe this Haskell-based solution, let&amp;#8217;s take a closer
look at the strings problem and review why a type-based approach makes
sense.  (If you already understand the strings problem and are
convinced that it is both important and tricky to solve, feel free
to skim the first third of this article.)&lt;/p&gt;


	&lt;h3&gt; Examining the &amp;#8220;strings problem&amp;#8221;&lt;/h3&gt;


	&lt;p&gt;Most web applications are just business-logic-driven string processors.  They
take strings from user-submitted forms, database queries, web-service
responses, templates, and myriad other sources, and they combine the
strings to generate yet more strings, which they emit as output and
fling across the Internet, into your web browser.&lt;/p&gt;


	&lt;p&gt;For example, consider this snippet of Ruby (on Rails) code that I used &lt;a href="http://blog.moertel.com/articles/2006/08/09/adding-reddit-and-del-icio-us-buttons-to-articles-in-typo"&gt;to
add submit-to-Reddit and submit-to-del.icio.us
buttons&lt;/a&gt;
to articles on my blog:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;def submit_this_article_links(article)
  site_list(article).map do |submit_title, submit_url, image_tag|
    %(&amp;lt;a href="#{h submit_url}" 
         title="#{h submit_title}: &amp;amp;#x201C;#{h article.title}&amp;amp;#x201D;" 
      &amp;gt;#{image_tag}&amp;lt;/a&amp;gt;)
  end.join("&amp;amp;#160;")
end

def site_list(article)
  u_title = u(article.title)
  u_url = u(url_of(article, false))
  [  # I really belong in a database table
    [ "Submit to Reddit.com",
      "http://reddit.com/submit?url=#{u_url}&amp;#38;title=#{u_title}",
      image_tag("reddit.gif", :size =&amp;gt; "18x18", :border =&amp;gt; 0)
    ],
    [ "Save to del.icio.us",
      "http://del.icio.us/post?v=2&amp;#38;url=#{u_url}&amp;#38;title=#{u_title}",
      image_tag("delicious.gif", :size =&amp;gt; "16x16", :border =&amp;gt; 0)
    ]
  ]
end
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;When writing this code, I had to keep track of at least three
different kinds of strings:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;Plain-old text&lt;/strong&gt;, e.g., article titles&lt;/li&gt;
		&lt;li&gt;&lt;strong&gt;URLs&lt;/strong&gt;, e.g., article permalinks&lt;/li&gt;
		&lt;li&gt;&lt;strong&gt;&lt;span class="caps"&gt;XHTML&lt;/span&gt; fragments&lt;/strong&gt;, e.g., the hypertext link to Reddit&amp;#8217;s submission form&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;In code like this, each type of string must conform to the
requirements of its own little language, and it&amp;#8217;s the programmer&amp;#8217;s job &amp;#8211; your job &amp;#8211; to make sure that differences in these requirements are accounted for
when combining strings.  Getting it right is a
difficult trick to pull off, and getting it right consistently is
&lt;a href="http://blog.moertel.com/articles/2006/10/12/if-unit-testing-cant-keep-rails-safe-from-string-escaping-problems-what-makes-you-think-it-will-keep-your-projects-safe"&gt;something even the best developers have difficulty doing&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;In the tiny snippet of code above, for example, I had to remember to
do all of these things:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;&lt;span class="caps"&gt;URL&lt;/span&gt;-escape (using the &lt;code&gt;u&lt;/code&gt; helper method) the article&amp;#8217;s title before inserting it into the submit-URL template&lt;/li&gt;
		&lt;li&gt;&lt;span class="caps"&gt;URL&lt;/span&gt;-escape the &lt;span class="caps"&gt;URL&lt;/span&gt; for the article&amp;#8217;s permalink before inserting it into the submit-URL template&lt;/li&gt;
		&lt;li&gt;&lt;span class="caps"&gt;HTML&lt;/span&gt;-escape (using the &lt;code&gt;h&lt;/code&gt; helper method) the final, expanded submit-URL template before inserting it into the hypertext-link template&lt;/li&gt;
		&lt;li&gt;&lt;span class="caps"&gt;HTML&lt;/span&gt;-escape the submit-title (e.g., &amp;#8220;Submit to Reddit&amp;#8221;) before inserting it into the hypertext-link template&lt;/li&gt;
		&lt;li&gt;&lt;span class="caps"&gt;HTML&lt;/span&gt;-escape the article&amp;#8217;s title before inserting it into the hypertext-link template&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;That&amp;#8217;s a lot to keep track of when coding.&lt;/p&gt;


	&lt;p&gt;But that&amp;#8217;s not all.  I also had to know &lt;em&gt;not&lt;/em&gt; to escape the result of
calling &lt;code&gt;image_tag&lt;/code&gt;, because that helper method returns
an &lt;span class="caps"&gt;HTML&lt;/span&gt; fragment, which is already in the language of the
hypertext-link template into which it is inserted.  Escaping it would
have turned the image-element markup into embedded text that happens
to look a lot like &lt;span class="caps"&gt;HTML&lt;/span&gt; markup.&lt;/p&gt;


	&lt;p&gt;And that&amp;#8217;s not the worst of it.  If you screw up any one of these
steps for the typical web application, you open
the door to a host of nasty problems.  If you&amp;#8217;re lucky, the damage
will be contained to broken links or a rendering problem that
most people won&amp;#8217;t notice, maybe a weird database error now and again.
In the worst case, however, you&amp;#8217;re screwed: Your application&amp;#8217;s
customers become vulnerable to &lt;a href="http://en.wikipedia.org/wiki/Cross_site_scripting"&gt;cross-site-scripting (XSS)
attacks&lt;/a&gt; and your
database is opened to &lt;a href="http://en.wikipedia.org/wiki/SQL_injection"&gt;injected
&lt;span class="caps"&gt;SQL&lt;/span&gt;&lt;/a&gt;, through which
enterprising crackers might steal your customers&amp;#8217; account data
or do even nastier things.&lt;/p&gt;


	&lt;p&gt;Clearly, the strings problem is common enough and nasty enough to merit
our attention.  Many of our favorite problem-stomping practices,
however, have not proved effective on the ever-tricky strings problem.&lt;/p&gt;


	&lt;h3&gt;Unit testing is an inefficient solution to the strings problem&lt;/h3&gt;


	&lt;p&gt;Unit testing is one of the most efficient programming practices for
increasing the quality of software.  If you write unit tests pervasively
as you code, you are likely to nip many kinds of programming problems
in the bud, saving time and effort, which you can then re-invest in
your code.  Further, unit-testing suites make for swell
regression-detection nets and thus free you to refactor crufty code
without fear of introducing breakage elsewhere.  As a result, you&amp;#8217;re
more likely to keep your code lean and mean.&lt;/p&gt;


	&lt;p&gt;Despite its general effectiveness, unit testing is an inefficient way
to defend against the perils of the strings problem.  That&amp;#8217;s because
the strings problem is caused by knowledge deficits, which you can&amp;#8217;t
test for.  If you don&amp;#8217;t realize that you must escape one &lt;span class="caps"&gt;URL&lt;/span&gt;
before you stuff it into another &lt;span class="caps"&gt;URL&lt;/span&gt;, you probably won&amp;#8217;t think to
write tests for that requirement.&lt;/p&gt;


	&lt;p&gt;Moreover, if you do think to write the tests, it&amp;#8217;s expensive to get
them right.  In most unit testing scenarios, getting the tests right
is usually easier or at least comparable in difficulty to getting the
code that&amp;#8217;s being tested right.  That&amp;#8217;s why unit testing is usually
so efficient.  For the strings problem, however, getting
the tests right is often much more expensive than writing typical
string-handling code.  In my code sample
above, for example, there are at least six ways the strings problem
can cause trouble.  How do you test for them all without making
a mistake?  It&amp;#8217;s not easy.&lt;/p&gt;


	&lt;p&gt;In sum, unit testing probably isn&amp;#8217;t the answer to the strings problem.&lt;/p&gt;


	&lt;h3&gt;Other solutions to the strings problem&lt;/h3&gt;


	&lt;p&gt;If unit testing isn&amp;#8217;t the answer, what is?&lt;/p&gt;


	&lt;p&gt;Joel Spolsky wrote about
the strings problem and &lt;a href="http://www.joelonsoftware.com/articles/Wrong.html"&gt;suggested that using Hungarian notation was
an effective
solution&lt;/a&gt;.
It might work, but it&amp;#8217;s clunky.&lt;/p&gt;


	&lt;p&gt;In the database-programming world, many programmers have adopted the
convention of never inserting a string into a &lt;span class="caps"&gt;SQL&lt;/span&gt; template by hand.
Instead, they insert placeholders, typically question marks,
into a template to indicate where they would like strings to be
inserted.  The template and the strings are then given
to a special function that safely inserts the strings, escaping them
as necessary.  In Ruby on Rails, which has a fairly typical
implementation, template expansion looks like this:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;Post.find_by_sql \
  [ "SELECT * FROM posts WHERE author = ? AND created &amp;gt; ?",
    author_id, start_date ]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The question-marks-in-the-template solution is effective, but it&amp;#8217;s
also clunky, especially when you&amp;#8217;re trying to insert a lot of strings.
By comparison, Ruby&amp;#8217;s native string-interpolation feature, in which the syntax
&lt;code&gt;#{...}&lt;/code&gt; lets us inject strings into a string template, is
unsafe but much easier to follow:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;chunkiness = "extra chunky" 
"I love #{chunkiness} bacon!" 
# ==&amp;gt; "I love extra chunky bacon!" 
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;In sum, the Hungarian-notation solution and the question-marks
solution are reasonable responses to the strings problem, but both are
clunky, especially when compared to the straightforwardness of
good-old string interpolation.&lt;/p&gt;


	&lt;p&gt;Perhaps we can do better.&lt;/p&gt;


	&lt;h3&gt; Eating and having one&amp;#8217;s cake: a type-based solution&lt;/h3&gt;


	&lt;p&gt;An ideal solution would combine the safety of the question-marks
solution with the straightforward convenience of string interpolation,
and it would work for all kinds of strings, not just &lt;span class="caps"&gt;SQL&lt;/span&gt;, and, because
I&amp;#8217;m implementing it in Haskell, it would lovingly nestle into
Haskell&amp;#8217;s type system and gain the full benefits of type-inferencing
goodness.&lt;/p&gt;


	&lt;p&gt;How would it work?  Well, let&amp;#8217;s back up and think about strings for a
moment.  We can divide strings into two classes: (1) those that
represent text, in which every character represents literally itself;
and (2) those that represent fragments of interpreted languages, such
as &lt;span class="caps"&gt;XML&lt;/span&gt; or &lt;span class="caps"&gt;SQL&lt;/span&gt;, where each character&amp;#8217;s interpretation depends on the
rules of the associated language.  In text, for example, an ampersand
(&amp;#8220;&amp;#38;&amp;#8221;) represents an ampersand, but in &lt;span class="caps"&gt;XML&lt;/span&gt; an ampersand represents the
start of a character-entity reference.&lt;/p&gt;


	&lt;p&gt;It doesn&amp;#8217;t make sense, then, to join text strings directly with
language-fragment strings.  If you did join them, text characters
could be misinterpreted as language characters.  For the same reason,
it doesn&amp;#8217;t make sense to join fragments of different languages
together.  (It does make sense, however, to &lt;em&gt;escape&lt;/em&gt; text strings or
language fragments &amp;#8220;into&amp;#8221; a target language and &lt;em&gt;then&lt;/em&gt; join them with
strings in the target language.)&lt;/p&gt;


	&lt;p&gt;A sound solution, therefore, should enforce the following fundamental,
safe-string-handling rule: &lt;em&gt;Do not allow strings that represent
fragments of one language to be directly joined with strings that
represent either plain text or fragments of another language&lt;/em&gt;.&lt;/p&gt;


	&lt;p&gt;The trick is making the computer enforce this rule for us.  As
it turns out, modern type systems absolutely love to do this kind of thing.&lt;/p&gt;


	&lt;h3&gt; A solution to the strings problem in Haskell&lt;/h3&gt;


	&lt;p&gt;Making the computer enforce our safe-string-handling rule in Haskell
is fairly easy.  All it takes is a little code.
(As we go through the following code, remember that
we&amp;#8217;re writing a library.  Normally, as users of the library, this
code would be invisible to us.)&lt;/p&gt;


	&lt;p&gt;To begin, we create a module for our code and export
the essential types and functions that make up our about-to-be-written
safe-string kernel:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_haskell "&gt;&lt;span class='keyword'&gt;module&lt;/span&gt; &lt;span class='conid'&gt;SafeStrings&lt;/span&gt;
&lt;span class='layout'&gt;(&lt;/span&gt;
  &lt;span class='conid'&gt;Language&lt;/span&gt;&lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='keyglyph'&gt;..&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;&lt;span class='layout'&gt;,&lt;/span&gt;
&lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='conid'&gt;SafeString&lt;/span&gt; &lt;span class='comment'&gt;-- we export the data type but not the constructors&lt;/span&gt;
&lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='varid'&gt;empty&lt;/span&gt;&lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='varid'&gt;frag&lt;/span&gt;&lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='varid'&gt;text&lt;/span&gt;
&lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='varid'&gt;cat&lt;/span&gt;&lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varop'&gt;+++&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
&lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='varid'&gt;render&lt;/span&gt;&lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='varid'&gt;renders&lt;/span&gt;&lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='varid'&gt;lang&lt;/span&gt;
&lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='varid'&gt;q&lt;/span&gt;
&lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='varid'&gt;declareSafeString&lt;/span&gt;
&lt;span class='layout'&gt;)&lt;/span&gt;
&lt;span class='keyword'&gt;where&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;In order to create safe strings that correspond to particular
languages, we need to tell the computer what we mean by &lt;em&gt;Language&lt;/em&gt;:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_haskell "&gt;&lt;span class='keyword'&gt;class&lt;/span&gt; &lt;span class='conid'&gt;Language&lt;/span&gt; &lt;span class='varid'&gt;l&lt;/span&gt; &lt;span class='keyword'&gt;where&lt;/span&gt;
    &lt;span class='varid'&gt;litfrag&lt;/span&gt;  &lt;span class='keyglyph'&gt;::&lt;/span&gt; &lt;span class='conid'&gt;String&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='varid'&gt;l&lt;/span&gt;   &lt;span class='comment'&gt;-- String is a literal language fragment&lt;/span&gt;
    &lt;span class='varid'&gt;littext&lt;/span&gt;  &lt;span class='keyglyph'&gt;::&lt;/span&gt; &lt;span class='conid'&gt;String&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='varid'&gt;l&lt;/span&gt;   &lt;span class='comment'&gt;-- String is literal text&lt;/span&gt;
    &lt;span class='varid'&gt;natrep&lt;/span&gt;   &lt;span class='keyglyph'&gt;::&lt;/span&gt; &lt;span class='varid'&gt;l&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;String&lt;/span&gt;   &lt;span class='comment'&gt;-- Gets the native-language representation&lt;/span&gt;
    &lt;span class='varid'&gt;language&lt;/span&gt; &lt;span class='keyglyph'&gt;::&lt;/span&gt; &lt;span class='varid'&gt;l&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;String&lt;/span&gt;   &lt;span class='comment'&gt;-- Gets the name of the language&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Here we&amp;#8217;re saying that &lt;em&gt;Language&lt;/em&gt; is the class of languages, i.e., all
data types &lt;em&gt;l&lt;/em&gt; for which we can provide four functions:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;&lt;em&gt;litfrag&lt;/em&gt; &amp;#8211; converts a string that represents a language fragment into a language fragment&lt;/li&gt;
		&lt;li&gt;&lt;em&gt;littext&lt;/em&gt; &amp;#8211; converts a string that represents plain text into a language fragment that represents the text (via escaping)&lt;/li&gt;
		&lt;li&gt;&lt;em&gt;natrep&lt;/em&gt; &amp;#8211;  converts a language fragment, verbatim, into a string that represents the language fragment&lt;/li&gt;
		&lt;li&gt;&lt;em&gt;language&lt;/em&gt; &amp;#8211; returns the name of the language associated with a given fragment&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;Further, we need to declare a few &amp;#8220;language laws&amp;#8221; that conforming
&lt;em&gt;Language&lt;/em&gt; types must obey.  These laws are for us.  They will keep us
honest when teaching the computer about new languages.  Here are the
two laws we will require language types to satisfy:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;em&gt;natrep&lt;/em&gt; (&lt;em&gt;litfrag&lt;/em&gt; &lt;em&gt;s&lt;/em&gt;) &lt;code&gt;==&lt;/code&gt; &lt;em&gt;s&lt;/em&gt;&lt;/li&gt;
		&lt;li&gt;&lt;em&gt;natrep&lt;/em&gt; (&lt;em&gt;littext&lt;/em&gt; &lt;em&gt;s&lt;/em&gt;) &lt;code&gt;==&lt;/code&gt; (&lt;em&gt;escape&lt;sub&gt;L&lt;/sub&gt;&lt;/em&gt; &lt;em&gt;s&lt;/em&gt;)&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;The first law requires that (&lt;em&gt;natrep&lt;/em&gt;&amp;#160;.&amp;#160;&lt;em&gt;litfrag&lt;/em&gt;) be
equivalent to the identity function for strings.  The second law
requires that (&lt;em&gt;natrep&lt;/em&gt;&amp;#160;.&amp;#160;&lt;em&gt;littext&lt;/em&gt;) be equivalent to
the text-escaping function for a given language &lt;em&gt;L&lt;/em&gt;.  For example,
for the language &lt;span class="caps"&gt;XML&lt;/span&gt;:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;natrep (litfrag "&amp;lt;em&amp;gt;wow!&amp;lt;/em&amp;gt;") ==&amp;gt; "&amp;lt;em&amp;gt;wow!&amp;lt;/em&amp;gt;" 
natrep (littext "ham &amp;#38; eggs")    ==&amp;gt; "ham &amp;amp;amp; eggs" 
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Next, let&amp;#8217;s construct a type-safe container for strings having
a known language:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_haskell "&gt;&lt;span class='keyword'&gt;data&lt;/span&gt; &lt;span class='conid'&gt;Language&lt;/span&gt; &lt;span class='varid'&gt;l&lt;/span&gt; &lt;span class='keyglyph'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;SafeString&lt;/span&gt; &lt;span class='varid'&gt;l&lt;/span&gt;
    &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='conid'&gt;SSEmpty&lt;/span&gt;
    &lt;span class='keyglyph'&gt;|&lt;/span&gt; &lt;span class='conid'&gt;SSFragment&lt;/span&gt; &lt;span class='varid'&gt;l&lt;/span&gt;
    &lt;span class='keyglyph'&gt;|&lt;/span&gt; &lt;span class='conid'&gt;SSCat&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='conid'&gt;SafeString&lt;/span&gt; &lt;span class='varid'&gt;l&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='conid'&gt;SafeString&lt;/span&gt; &lt;span class='varid'&gt;l&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;This data-type definition says that if &lt;em&gt;l&lt;/em&gt; is a language, we
can construct &lt;em&gt;SafeString&lt;/em&gt; values for that language.  Each value can
represent an empty fragment of the language (via &lt;em&gt;SSEmpty&lt;/em&gt;), a
non-empty fragment of the language (via &lt;em&gt;SSFragment&lt;/em&gt;), or the
concatenation of two other &lt;em&gt;SafeString&lt;/em&gt; values for the language
(via &lt;em&gt;SSCat&lt;/em&gt;).&lt;/p&gt;


	&lt;p&gt;Now comes the interesting part.  We are going to leverage the type
system to enforce the safe-string-handling rule for us.&lt;/p&gt;


	&lt;p&gt;We will do this using the &lt;em&gt;SafeString&lt;/em&gt; data type we just defined.
We have already placed the data type&amp;#8217;s definition into a module that
does &lt;em&gt;not&lt;/em&gt; export the type&amp;#8217;s data constructors.  That means we will not
be able to create &lt;em&gt;SafeString&lt;/em&gt; values for ourselves.  Instead, we must
ask a small set of kernel functions, which &lt;em&gt;are&lt;/em&gt; exported, to create the
values on our behalf.&lt;/p&gt;


	&lt;p&gt;These kernel functions, which we are about to write,
will create &lt;em&gt;SafeString&lt;/em&gt; values only in accordance with our
safe-string-handling rule.  In particular, they will require us
to &lt;em&gt;certify&lt;/em&gt; that an existing string represents either text or a language
fragment before creating a corresponding &lt;em&gt;SafeString&lt;/em&gt; value
for us.  From then on, the type system will know
which language the string is associated with and prevent us from
joining it to regular strings or to &lt;em&gt;SafeString&lt;/em&gt; values associated
with other languages.&lt;/p&gt;


	&lt;p&gt;Let&amp;#8217;s write these constructor functions now:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_haskell "&gt;&lt;span class='varid'&gt;empty&lt;/span&gt;      &lt;span class='keyglyph'&gt;::&lt;/span&gt; &lt;span class='conid'&gt;Language&lt;/span&gt; &lt;span class='varid'&gt;l&lt;/span&gt; &lt;span class='keyglyph'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;SafeString&lt;/span&gt; &lt;span class='varid'&gt;l&lt;/span&gt;
&lt;span class='varid'&gt;empty&lt;/span&gt;       &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='conid'&gt;SSEmpty&lt;/span&gt;

&lt;span class='varid'&gt;frag&lt;/span&gt;&lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='varid'&gt;text&lt;/span&gt; &lt;span class='keyglyph'&gt;::&lt;/span&gt; &lt;span class='conid'&gt;Language&lt;/span&gt; &lt;span class='varid'&gt;l&lt;/span&gt; &lt;span class='keyglyph'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;String&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;SafeString&lt;/span&gt; &lt;span class='varid'&gt;l&lt;/span&gt;
&lt;span class='varid'&gt;frag&lt;/span&gt; &lt;span class='varid'&gt;f&lt;/span&gt;      &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='conid'&gt;SSFragment&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;litfrag&lt;/span&gt; &lt;span class='varid'&gt;f&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
&lt;span class='varid'&gt;text&lt;/span&gt; &lt;span class='varid'&gt;s&lt;/span&gt;      &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='conid'&gt;SSFragment&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;littext&lt;/span&gt; &lt;span class='varid'&gt;s&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Here&amp;#8217;s what the functions do:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;em&gt;empty&lt;/em&gt; &amp;#8211; creates an empty &lt;em&gt;SafeString&lt;/em&gt; in the &lt;em&gt;Language l&lt;/em&gt;&lt;/li&gt;
		&lt;li&gt;&lt;em&gt;frag f&lt;/em&gt; &amp;#8211; takes a string that you certify as representing a fragment in the &lt;em&gt;Language l&lt;/em&gt; and returns a corresponding &lt;em&gt;SafeString&lt;/em&gt;&lt;/li&gt;
		&lt;li&gt;&lt;em&gt;text s&lt;/em&gt; &amp;#8211; takes a string that you certify as representing text and returns a corresponding &lt;em&gt;SafeString&lt;/em&gt; in the &lt;em&gt;Language l&lt;/em&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Once the kernel creates &lt;em&gt;SafeString&lt;/em&gt; values for us, we need some way
to combine them safely.  Thus we define the &lt;code&gt;(+++)&lt;/code&gt;
operator and the &lt;em&gt;cat&lt;/em&gt; function:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_haskell "&gt;&lt;span class='comment'&gt;-- join two SafeStrings of the same language&lt;/span&gt;
&lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varop'&gt;+++&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='keyglyph'&gt;::&lt;/span&gt; &lt;span class='conid'&gt;Language&lt;/span&gt; &lt;span class='varid'&gt;l&lt;/span&gt; &lt;span class='keyglyph'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;SafeString&lt;/span&gt; &lt;span class='varid'&gt;l&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;SafeString&lt;/span&gt; &lt;span class='varid'&gt;l&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;SafeString&lt;/span&gt; &lt;span class='varid'&gt;l&lt;/span&gt;
&lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varop'&gt;+++&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;  &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='conid'&gt;SSCat&lt;/span&gt;

&lt;span class='comment'&gt;-- join a list of same-language SafeStrings&lt;/span&gt;
&lt;span class='varid'&gt;cat&lt;/span&gt;   &lt;span class='keyglyph'&gt;::&lt;/span&gt; &lt;span class='conid'&gt;Language&lt;/span&gt; &lt;span class='varid'&gt;l&lt;/span&gt; &lt;span class='keyglyph'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='keyglyph'&gt;[&lt;/span&gt;&lt;span class='conid'&gt;SafeString&lt;/span&gt; &lt;span class='varid'&gt;l&lt;/span&gt;&lt;span class='keyglyph'&gt;]&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;SafeString&lt;/span&gt; &lt;span class='varid'&gt;l&lt;/span&gt;
&lt;span class='varid'&gt;cat&lt;/span&gt;    &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='varid'&gt;foldr&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varop'&gt;+++&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='varid'&gt;empty&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Finally, we need a way to convert &lt;em&gt;SafeString&lt;/em&gt; values into normal
strings so that we can pass them through the boundaries of our
safe-string-protected code and into the outside world.  For this,
we write the &lt;em&gt;render&lt;/em&gt; function:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_haskell "&gt;&lt;span class='varid'&gt;render&lt;/span&gt; &lt;span class='varid'&gt;ss&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='varid'&gt;renders&lt;/span&gt; &lt;span class='varid'&gt;ss&lt;/span&gt; &lt;span class='str'&gt;""&lt;/span&gt;

&lt;span class='varid'&gt;renders&lt;/span&gt; &lt;span class='conid'&gt;SSEmpty&lt;/span&gt;        &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='varid'&gt;id&lt;/span&gt;
&lt;span class='varid'&gt;renders&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='conid'&gt;SSFragment&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;natrep&lt;/span&gt; &lt;span class='varid'&gt;a&lt;/span&gt; &lt;span class='varop'&gt;++&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
&lt;span class='varid'&gt;renders&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='conid'&gt;SSCat&lt;/span&gt; &lt;span class='varid'&gt;l&lt;/span&gt; &lt;span class='varid'&gt;r&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;    &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='varid'&gt;renders&lt;/span&gt; &lt;span class='varid'&gt;l&lt;/span&gt; &lt;span class='varop'&gt;.&lt;/span&gt; &lt;span class='varid'&gt;renders&lt;/span&gt; &lt;span class='varid'&gt;r&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;(Don&amp;#8217;t worry about the &lt;em&gt;renders&lt;/em&gt; stuff.  It implements
a Haskell idiom for fast string concatenation.)&lt;/p&gt;


	&lt;p&gt;As a convenience, let&amp;#8217;s round out our kernel with a &lt;em&gt;Show&lt;/em&gt; instance
that tells Haskell how to format
&lt;em&gt;SafeString&lt;/em&gt; values for display.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_haskell "&gt;&lt;span class='keyword'&gt;instance&lt;/span&gt; &lt;span class='conid'&gt;Language&lt;/span&gt; &lt;span class='varid'&gt;l&lt;/span&gt; &lt;span class='keyglyph'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;Show&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='conid'&gt;SafeString&lt;/span&gt; &lt;span class='varid'&gt;l&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='keyword'&gt;where&lt;/span&gt;
    &lt;span class='varid'&gt;showsPrec&lt;/span&gt; &lt;span class='keyword'&gt;_&lt;/span&gt; &lt;span class='varid'&gt;ss&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt;
        &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;lang&lt;/span&gt; &lt;span class='varid'&gt;ss&lt;/span&gt; &lt;span class='varop'&gt;++&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='varop'&gt;.&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='str'&gt;":\""&lt;/span&gt; &lt;span class='varop'&gt;++&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='varop'&gt;.&lt;/span&gt; &lt;span class='varid'&gt;renders&lt;/span&gt; &lt;span class='varid'&gt;ss&lt;/span&gt; &lt;span class='varop'&gt;.&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='chr'&gt;'"'&lt;/span&gt;&lt;span class='conop'&gt;:&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;

&lt;span class='varid'&gt;lang&lt;/span&gt; &lt;span class='varid'&gt;ss&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt;
    &lt;span class='keyword'&gt;let&lt;/span&gt; &lt;span class='conid'&gt;SSFragment&lt;/span&gt; &lt;span class='varid'&gt;e&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='varid'&gt;ss&lt;/span&gt; &lt;span class='keyword'&gt;in&lt;/span&gt; &lt;span class='varid'&gt;language&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;undefined&lt;/span&gt; &lt;span class='varop'&gt;`asTypeOf`&lt;/span&gt; &lt;span class='varid'&gt;e&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;And that&amp;#8217;s our SafeStrings kernel.&lt;/p&gt;


	&lt;h3&gt; Another look at the SafeStrings kernel&lt;/h3&gt;


	&lt;p&gt;The following illustration, complete with poorly chosen colors, provides a
visual summary of our system:&lt;/p&gt;


&lt;p style="text-align: center"&gt;
&lt;img src="http://community.moertel.com/~thor/pix/20060908/safe-strings.png" title="Stunning visual interpretation of the SafeStrings kernel and its relationship to the evil outside world" alt="Stunning visual interpretation of the SafeStrings kernel and its relationship to the evil outside world" /&gt;
&lt;/p&gt;

	&lt;p&gt;(Don&amp;#8217;t worry about the &lt;code&gt;$(q ...)&lt;/code&gt; stuff for the
moment, we&amp;#8217;ll talk about it later.)&lt;/p&gt;


	&lt;p&gt;Activating our mad art-interpretation skillz, we can
now decipher the illustration:&lt;/p&gt;


	&lt;p&gt;&lt;em&gt;Regular strings gain &amp;#8220;admittance&amp;#8221; to the SafeStrings kernel only
via the &lt;/em&gt;text&lt;em&gt; and &lt;/em&gt;frag&lt;em&gt; certification functions, which
we use to create corresponding safe strings for a given language.
Once created, the safe strings live their entire lives in the
fleshy-colored, egg-shaped protective sac that is the kernel, whose
safe-string functions and operators use Haskell&amp;#8217;s type system to
prevent us from accidentally mixing the strings in unsafe
ways. Further, because the kernel does not export its underlying data
structures, we can&amp;#8217;t screw around with the innards of our safe strings to
break the kernel&amp;#8217;s promises.  When our safe strings have finally
reached their ultimate, beautiful state, we can &lt;/em&gt;render&lt;em&gt; them
into regular strings and pass them bravely into the cruel outside
world &amp;#8211; where, most likely, somebody else&amp;#8217;s broken code will screw
them up anyway.  But at least we tried.&lt;/em&gt;&lt;/p&gt;


	&lt;h3&gt;Our first SafeString module: SafeXml&lt;/h3&gt;


	&lt;p&gt;Now that we have written our SafeStrings kernel, let&amp;#8217;s use it to
create a SafeXml module that we can use for working with &lt;span class="caps"&gt;XML&lt;/span&gt;.
Again, we will be writing library code that under normal
circumstances would be hidden from view.&lt;/p&gt;


	&lt;p&gt;First, we will create a new module that uses the SafeStrings kernel:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_haskell "&gt;&lt;span class='keyword'&gt;module&lt;/span&gt; &lt;span class='conid'&gt;SafeXml&lt;/span&gt;
&lt;span class='layout'&gt;(&lt;/span&gt; &lt;span class='conid'&gt;Xml&lt;/span&gt;&lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='varid'&gt;xml&lt;/span&gt;&lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='varid'&gt;renderXml&lt;/span&gt;&lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='keyword'&gt;module&lt;/span&gt; &lt;span class='conid'&gt;SafeStrings&lt;/span&gt; &lt;span class='layout'&gt;)&lt;/span&gt;
&lt;span class='keyword'&gt;where&lt;/span&gt;
&lt;span class='keyword'&gt;import&lt;/span&gt; &lt;span class='conid'&gt;SafeStrings&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Next, we will create a wrapper type to testify
that a string represents a fragment of &lt;span class="caps"&gt;XML&lt;/span&gt;:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_haskell "&gt;&lt;span class='keyword'&gt;newtype&lt;/span&gt; &lt;span class='conid'&gt;XmlString&lt;/span&gt;
    &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='conid'&gt;XmlString&lt;/span&gt; &lt;span class='layout'&gt;{&lt;/span&gt; &lt;span class='varid'&gt;unXmlString&lt;/span&gt; &lt;span class='keyglyph'&gt;::&lt;/span&gt; &lt;span class='conid'&gt;String&lt;/span&gt; &lt;span class='layout'&gt;}&lt;/span&gt;
    &lt;span class='keyword'&gt;deriving&lt;/span&gt; &lt;span class='conid'&gt;Show&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;If you go back and look at the export list for the module, you&amp;#8217;ll see
that the &lt;em&gt;XmlString&lt;/em&gt; data type is not exported.  It is internal to the
module, and thus we, as clients of the module, can&amp;#8217;t create values of
that type.  That means we can&amp;#8217;t &amp;#8220;forge&amp;#8221; &lt;span class="caps"&gt;XML&lt;/span&gt; strings into existence.
We can create them only through the safe-string kernel, and even then
only by certifying a regular string as representing text or a language
fragment.  (The kernel, in turn, will create the needed values through
the &lt;em&gt;Language&lt;/em&gt; interface, which we now discuss.)&lt;/p&gt;


	&lt;p&gt;Like all good language types, &lt;em&gt;XmlString&lt;/em&gt; needs to be a member of the
&lt;em&gt;Language&lt;/em&gt; type class, so we provide the necessary instance functions:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_haskell "&gt;&lt;span class='keyword'&gt;instance&lt;/span&gt; &lt;span class='conid'&gt;Language&lt;/span&gt; &lt;span class='conid'&gt;XmlString&lt;/span&gt; &lt;span class='keyword'&gt;where&lt;/span&gt;
    &lt;span class='varid'&gt;litfrag&lt;/span&gt;  &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='conid'&gt;XmlString&lt;/span&gt;
    &lt;span class='varid'&gt;littext&lt;/span&gt;  &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='conid'&gt;XmlString&lt;/span&gt; &lt;span class='varop'&gt;.&lt;/span&gt; &lt;span class='varid'&gt;escapeXml&lt;/span&gt;
    &lt;span class='varid'&gt;natrep&lt;/span&gt;   &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='varid'&gt;unXmlString&lt;/span&gt;
    &lt;span class='varid'&gt;language&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='varid'&gt;const&lt;/span&gt; &lt;span class='str'&gt;"xml"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Note that the functions satisfy the language laws
we defined earlier.  (The proof follows immediately from the definitions
of &lt;em&gt;XmlString&lt;/em&gt;, &lt;em&gt;unXmlString&lt;/em&gt;, and &lt;em&gt;escapeXml&lt;/em&gt;.)&lt;/p&gt;


	&lt;p&gt;Next, we need to write a function to implement the escaping
rule for &lt;span class="caps"&gt;XML&lt;/span&gt;:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_haskell "&gt;&lt;span class='varid'&gt;escapeXml&lt;/span&gt; &lt;span class='varid'&gt;xs&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt;
    &lt;span class='varid'&gt;concatMap&lt;/span&gt; &lt;span class='varid'&gt;esc&lt;/span&gt; &lt;span class='varid'&gt;xs&lt;/span&gt;
  &lt;span class='keyword'&gt;where&lt;/span&gt;
    &lt;span class='varid'&gt;esc&lt;/span&gt; &lt;span class='chr'&gt;'&amp;lt;'&lt;/span&gt;  &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='str'&gt;"&amp;amp;lt;"&lt;/span&gt;
    &lt;span class='varid'&gt;esc&lt;/span&gt; &lt;span class='chr'&gt;'&amp;amp;'&lt;/span&gt;  &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='str'&gt;"&amp;amp;amp;"&lt;/span&gt;
    &lt;span class='varid'&gt;esc&lt;/span&gt; &lt;span class='chr'&gt;'"'&lt;/span&gt;  &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='str'&gt;"&amp;amp;#34;"&lt;/span&gt;
    &lt;span class='varid'&gt;esc&lt;/span&gt; &lt;span class='chr'&gt;'\''&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='str'&gt;"&amp;amp;#39;"&lt;/span&gt;
    &lt;span class='varid'&gt;esc&lt;/span&gt; &lt;span class='varid'&gt;x&lt;/span&gt;    &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='keyglyph'&gt;[&lt;/span&gt;&lt;span class='varid'&gt;x&lt;/span&gt;&lt;span class='keyglyph'&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Next, because we expect to work with &lt;span class="caps"&gt;XML&lt;/span&gt; frequently, we will create a
convenient type synonym, &lt;em&gt;Xml&lt;/em&gt;, for &lt;em&gt;SafeString&lt;/em&gt; values that represent
&lt;span class="caps"&gt;XML&lt;/span&gt;:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_haskell "&gt;&lt;span class='keyword'&gt;type&lt;/span&gt; &lt;span class='conid'&gt;Xml&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='conid'&gt;SafeString&lt;/span&gt; &lt;span class='conid'&gt;XmlString&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Finally, we will create
a few convenience functions to create and render &lt;span class="caps"&gt;XML&lt;/span&gt; fragments.  These
functions are identical to the SafeString kernel&amp;#8217;s &lt;em&gt;frag&lt;/em&gt; and &lt;em&gt;render&lt;/em&gt;
functions but for the &lt;em&gt;Xml&lt;/em&gt; type exclusively.  When we use these
functions, we won&amp;#8217;t need to provide additional type annotations; the
computer will know we are dealing with &lt;span class="caps"&gt;XML&lt;/span&gt; strings:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_haskell "&gt;&lt;span class='varid'&gt;xml&lt;/span&gt; &lt;span class='keyglyph'&gt;::&lt;/span&gt; &lt;span class='conid'&gt;String&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;Xml&lt;/span&gt;
&lt;span class='varid'&gt;xml&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='varid'&gt;frag&lt;/span&gt;

&lt;span class='varid'&gt;renderXml&lt;/span&gt; &lt;span class='keyglyph'&gt;::&lt;/span&gt; &lt;span class='conid'&gt;Xml&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;String&lt;/span&gt;
&lt;span class='varid'&gt;renderXml&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='varid'&gt;render&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;And we&amp;#8217;re done.&lt;/p&gt;


	&lt;p&gt;Before going on, let me point out two things:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;If you think the code we have written so far is long or perhaps confusing, please remember that it is &lt;em&gt;library code&lt;/em&gt;.  Typically, you would never see it.  All you would do is &lt;code&gt;import SafeXml&lt;/code&gt; and start using the library.&lt;/li&gt;
		&lt;li&gt;The SafeXml implementation is formulaic, and we can replace all of it except for the escaping function&amp;#8217;s definition with a single line of code, something we will do later.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;h3&gt; A quick test drive of our SafeXml module&lt;/h3&gt;


	&lt;p&gt;Let&amp;#8217;s give our SafeXml module a spin in the &lt;span class="caps"&gt;GHC&lt;/span&gt; interactive shell.&lt;/p&gt;


	&lt;p&gt;We can create an &lt;span class="caps"&gt;XML&lt;/span&gt; fragment by certifying that a regular string
represents a language fragment (via the &lt;em&gt;frag&lt;/em&gt; function) and telling
Haskell that we expect a result of type &lt;em&gt;Xml&lt;/em&gt;.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;Ok, modules loaded: SafeXml, SafeStrings.
*SafeXml&amp;gt; frag "&amp;lt;em&amp;gt;wow!&amp;lt;/em&amp;gt;" :: Xml
xml:"&amp;lt;em&amp;gt;wow!&amp;lt;/em&amp;gt;" 
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Note how the output is prefixed with the label &amp;#8220;xml:&amp;#8221; 
to tell us that our kernel certifies this value to represent an &lt;span class="caps"&gt;XML&lt;/span&gt; fragment.&lt;/p&gt;


	&lt;p&gt;Because entering type annotations can be inconvenient, we can instead
use the &lt;em&gt;xml&lt;/em&gt; function, which certifies a string not just as a
fragment but as an &lt;span class="caps"&gt;XML&lt;/span&gt; fragment:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;*SafeXml&amp;gt; xml "&amp;lt;em&amp;gt;wow!&amp;lt;/em&amp;gt;" 
xml:"&amp;lt;em&amp;gt;wow!&amp;lt;/em&amp;gt;" 
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;If we want to represent text in &lt;span class="caps"&gt;XML&lt;/span&gt;, the kernel will automatically
escape it for us:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;*SafeXml&amp;gt; text "ham &amp;#38; eggs" :: Xml
xml:"ham &amp;amp;amp; eggs" 
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Now let&amp;#8217;s try to do something naughty.  Will the type system
let us?&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;*SafeXml&amp;gt; let someXml = xml "&amp;lt;em&amp;gt;Hi!&amp;lt;/em&amp;gt;" 
*SafeXml&amp;gt; let plainOldText = "ham &amp;#38; eggs" 
*SafeXml&amp;gt; someXml ++ plainOldText

&amp;lt;interactive&amp;gt;:1:0:
    Couldn't match `[a]' against `Xml'
      Expected type: [a]
      Inferred type: Xml
    In the first argument of `(++)', namely `someXml'
    In the definition of `it': it = someXml ++ plainOldText
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;In Haskell, the &lt;code&gt;(++)&lt;/code&gt; operator is used (among
other things) to join strings.  In the code above, we tried
to use this operator to join an &lt;span class="caps"&gt;XML&lt;/span&gt; fragment to a plain-old
string, which would have violated our safe-string-handling rule.
Fortunately, we were unable to fool the type system into
allowing this ill-conceived union to occur.  Note that our
mistake was caught at compile time, before the code was
ever converted into executable form.&lt;/p&gt;


	&lt;p&gt;Perhaps we can persuade our newly-defined &lt;code&gt;(+++)&lt;/code&gt;
operator to make the union:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;*SafeXml&amp;gt; someXml +++ plainOldText

&amp;lt;interactive&amp;gt;:1:12:
    Couldn't match `SafeString XmlString' against `[Char]'
      Expected type: SafeString XmlString
      Inferred type: [Char]
    In the second argument of `(+++)', namely `plainOldText'
    In the definition of `it': it = someXml +++ plainOldText
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Again, the type system has prevented us from doing something
naughty.  If, however, we certify that the plain-old string represents
text, we can make a safe union:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;*SafeXml&amp;gt; someXml +++ text plainOldText
xml:"&amp;lt;em&amp;gt;Hi!&amp;lt;/em&amp;gt;ham &amp;amp;amp; eggs" 
&lt;/code&gt;&lt;/pre&gt;

	&lt;h3&gt;Syntactic sugar for safe strings&lt;/h3&gt;


	&lt;p&gt;Not having to worry about the strings problem anymore is fabulous and
all, but having to type in &lt;em&gt;frag&lt;/em&gt;, &lt;em&gt;text&lt;/em&gt;, and &lt;code&gt;+++&lt;/code&gt; is
kind of clunky.  Let&amp;#8217;s get rid of the clunkiness by introducing some
syntactic sugar.&lt;/p&gt;


&lt;p&gt;The common case when dealing with strings in web applications is
templates.  For example, here&amp;#8217;s a simplified version of the
&lt;code&gt;link_to&lt;/code&gt; method from the deservedly popular &lt;a href="http://www.rubyonrails.com/"&gt;Ruby on
Rails&lt;/a&gt;.  The method wraps a hypertext link
around some content by &amp;#8220;interpolating&amp;#8221; the content and a &lt;span class="caps"&gt;URL&lt;/span&gt;
into a link template:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# NOTE: this example is in Ruby

def link_to(content_xhtml, url)
  "&amp;lt;a href=\"#{h url}\"&amp;gt;#{content_xhtml}&amp;lt;/a&amp;gt;" 
end
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;In this code, we need to &lt;span class="caps"&gt;HTML&lt;/span&gt;-escape the &lt;span class="caps"&gt;URL&lt;/span&gt; (via the &lt;code&gt;h&lt;/code&gt;
helper) before interpolating it
into the template.  We do not need to escape the content, however,
because it is already in the template&amp;#8217;s language, &lt;span class="caps"&gt;XHTML&lt;/span&gt;.&lt;/p&gt;


	&lt;p&gt;Now, to introduce our syntactic sugar, here&amp;#8217;s &lt;code&gt;link_to&lt;/code&gt;
rewritten in Haskell and using safe strings:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_haskell "&gt;&lt;span class='comment'&gt;-- Haskell code&lt;/span&gt;

&lt;span class='varid'&gt;link_to&lt;/span&gt; &lt;span class='keyglyph'&gt;::&lt;/span&gt; &lt;span class='conid'&gt;Xhtml&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;Url&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;Xhtml&lt;/span&gt;
&lt;span class='varid'&gt;link_to&lt;/span&gt; &lt;span class='varid'&gt;content&lt;/span&gt; &lt;span class='varid'&gt;url&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt;
    &lt;span class='varop'&gt;$&lt;/span&gt;&lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;q&lt;/span&gt; &lt;span class='str'&gt;"&amp;lt;a href=\"#{r url}\"&amp;gt;#{=content}&amp;lt;/a&amp;gt;"&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;The type signature makes clear to everybody that the &lt;em&gt;content&lt;/em&gt;
parameter is &lt;span class="caps"&gt;XHTML&lt;/span&gt;, the &lt;em&gt;url&lt;/em&gt; parameter is a &lt;span class="caps"&gt;URL&lt;/span&gt;, and the result is
&lt;span class="caps"&gt;XHTML&lt;/span&gt;.  The signature isn&amp;#8217;t needed, but &lt;code&gt;link_to&lt;/code&gt; is the
stuff of libraries, and so annotations are good form.&lt;/p&gt;


	&lt;p&gt;The interpolation syntax is like Ruby&amp;#8217;s, but with
slightly different modifiers:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;The template-quoting syntax is &lt;code&gt;$(q "this is a template")&lt;/code&gt;.  (Mnemonic: &lt;code&gt;q&lt;/code&gt; for quote).&lt;/li&gt;
		&lt;li&gt;Within a template, we can interpolate variables using the familiar &lt;code&gt;#{var}&lt;/code&gt; syntax.&lt;/li&gt;
		&lt;li&gt;If an interpolated variable holds a plain string, it will be escaped into the template automatically.&lt;/li&gt;
		&lt;li&gt;If an interpolated variable holds a safe string, we must use an &lt;em&gt;interpolation modifier&lt;/em&gt; to specify how it should be interpolated (to avoid ambiguity):
	&lt;ul&gt;
	&lt;li&gt;&lt;code&gt;#{r var}&lt;/code&gt; renders the safe string in &lt;em&gt;var&lt;/em&gt; into text, and then interpolates the text into the template, escaping as necessary (mnemonic: &lt;code&gt;r&lt;/code&gt; for &lt;em&gt;render&lt;/em&gt;).&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;#{= var}&lt;/code&gt; inserts the safe string in &lt;em&gt;var&lt;/em&gt; directly into the template, which must be of the same language (mnemonic: &lt;code&gt;=&lt;/code&gt; for &lt;em&gt;equal language types&lt;/em&gt;).&lt;/li&gt;
	&lt;/ul&gt;
	&lt;/li&gt;
		&lt;li&gt;As a bonus, &lt;code&gt;#{s var}&lt;/code&gt; interpolates any &lt;em&gt;Show&lt;/em&gt;-able value in &lt;em&gt;var&lt;/em&gt; into the template as text, escaping as necessary.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;It&amp;#8217;s pretty easy to tell which interpolation option is right for any
situation, but late-night coding sessions make fools of us all.
That&amp;#8217;s why the type system is there to catch us when we make a dumb mistake.&lt;/p&gt;


	&lt;p&gt;Let&amp;#8217;s try out the sugary &lt;code&gt;link_to&lt;/code&gt; method:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;&amp;gt; link_to (text "Tom's Weblog") (url "http://blog.moertel.com/")
xml:"&amp;lt;a href="http://blog.moertel.com/"&amp;gt;Tom's Weblog&amp;lt;/a&amp;gt;" 
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Let&amp;#8217;s take advantage of type inferencing in the next example:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;&amp;gt; link_to $(q "&amp;lt;em&amp;gt;Espresso!&amp;lt;/em&amp;gt;")
          $(q "http://google.com/search?q=espresso&amp;#38;oe=utf-8")

xml:"&amp;lt;a href="http://google.com/search?q=espresso&amp;amp;amp;oe=utf-8"&amp;gt;
     &amp;lt;em&amp;gt;Espresso!&amp;lt;/em&amp;gt;&amp;lt;/a&amp;gt;" 
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;In the above example, we supplied templates as input parameters.
Haskell figured out their types and took care of the escaping (or not
escaping) for us.&lt;/p&gt;


	&lt;p&gt;Now that we know what the syntactic sugar looks like, let&amp;#8217;s
see how to implement it.&lt;/p&gt;


	&lt;h3&gt; Implementing the syntactic sugar using Template Haskell&lt;/h3&gt;


	&lt;p&gt;We implement the SafeString library&amp;#8217;s syntactic sugar using Template
Haskell.  A small function &lt;code&gt;q&lt;/code&gt; (for &amp;#8220;quote&amp;#8221;) parses the
sugared syntax at compile time and emits equivalent code using our
safe-string functions &lt;code&gt;frag&lt;/code&gt;, &lt;code&gt;text&lt;/code&gt;, and so on.
For example, the following sugar:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_haskell "&gt;&lt;span class='varop'&gt;$&lt;/span&gt;&lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;q&lt;/span&gt; &lt;span class='str'&gt;"&amp;lt;em&amp;gt;#{mystr}&amp;lt;/em&amp;gt;"&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;becomes the following code:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_haskell "&gt;&lt;span class='varid'&gt;cat&lt;/span&gt; &lt;span class='keyglyph'&gt;[&lt;/span&gt;&lt;span class='varid'&gt;frag&lt;/span&gt; &lt;span class='str'&gt;"&amp;lt;em&amp;gt;"&lt;/span&gt;&lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='varid'&gt;text&lt;/span&gt; &lt;span class='varid'&gt;mystr&lt;/span&gt;&lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='varid'&gt;frag&lt;/span&gt; &lt;span class='str'&gt;"&amp;lt;/em&amp;gt;"&lt;/span&gt;&lt;span class='keyglyph'&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;The code that makes it happen is fairly straightforward if you know
Template Haskell, so I&amp;#8217;ll skip the explanation because this article
is already way too long.  As usual, it&amp;#8217;s library code, so normally we
wouldn&amp;#8217;t see or care about it.  All we care about is the &lt;code&gt;$(q
"...")&lt;/code&gt; sugar that the code makes available to us.&lt;/p&gt;


	&lt;p&gt;Here it is:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_haskell "&gt;&lt;span class='keyword'&gt;import&lt;/span&gt; &lt;span class='conid'&gt;Language&lt;/span&gt;&lt;span class='varop'&gt;.&lt;/span&gt;&lt;span class='conid'&gt;Haskell&lt;/span&gt;&lt;span class='varop'&gt;.&lt;/span&gt;&lt;span class='conid'&gt;TH&lt;/span&gt;
&lt;span class='keyword'&gt;import&lt;/span&gt; &lt;span class='varid'&gt;qualified&lt;/span&gt; &lt;span class='conid'&gt;Text&lt;/span&gt;&lt;span class='varop'&gt;.&lt;/span&gt;&lt;span class='conid'&gt;ParserCombinators&lt;/span&gt;&lt;span class='varop'&gt;.&lt;/span&gt;&lt;span class='conid'&gt;ReadP&lt;/span&gt; &lt;span class='keyword'&gt;as&lt;/span&gt; &lt;span class='conid'&gt;P&lt;/span&gt;

&lt;span class='comment'&gt;-- Convert template sugar into calls to frag, text, cat, etc.&lt;/span&gt;
&lt;span class='comment'&gt;-- This function is exported by the SafeStrings module.&lt;/span&gt;

&lt;span class='varid'&gt;q&lt;/span&gt; &lt;span class='varid'&gt;spec&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt;
    &lt;span class='keyglyph'&gt;[&lt;/span&gt;&lt;span class='keyglyph'&gt;|&lt;/span&gt; &lt;span class='varid'&gt;cat&lt;/span&gt; &lt;span class='varop'&gt;$&lt;/span&gt;&lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;parts&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='keyglyph'&gt;|&lt;/span&gt;&lt;span class='keyglyph'&gt;]&lt;/span&gt;
  &lt;span class='keyword'&gt;where&lt;/span&gt;
    &lt;span class='varid'&gt;parts&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='keyword'&gt;case&lt;/span&gt; &lt;span class='varid'&gt;xparse&lt;/span&gt; &lt;span class='varid'&gt;spec&lt;/span&gt; &lt;span class='keyword'&gt;of&lt;/span&gt;
        &lt;span class='keyglyph'&gt;[&lt;/span&gt;&lt;span class='keyglyph'&gt;]&lt;/span&gt;   &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='varid'&gt;error&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='str'&gt;"bad template: "&lt;/span&gt; &lt;span class='varop'&gt;++&lt;/span&gt; &lt;span class='varid'&gt;show&lt;/span&gt; &lt;span class='varid'&gt;spec&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
        &lt;span class='varid'&gt;ps&lt;/span&gt;&lt;span class='conop'&gt;:&lt;/span&gt;&lt;span class='keyword'&gt;_&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='varid'&gt;foldr&lt;/span&gt; &lt;span class='varid'&gt;gen&lt;/span&gt; &lt;span class='keyglyph'&gt;[&lt;/span&gt;&lt;span class='keyglyph'&gt;|&lt;/span&gt; &lt;span class='keyglyph'&gt;[&lt;/span&gt;&lt;span class='keyglyph'&gt;]&lt;/span&gt; &lt;span class='keyglyph'&gt;|&lt;/span&gt;&lt;span class='keyglyph'&gt;]&lt;/span&gt; &lt;span class='varid'&gt;ps&lt;/span&gt;
    &lt;span class='varid'&gt;gen&lt;/span&gt; &lt;span class='varid'&gt;p&lt;/span&gt; &lt;span class='varid'&gt;ps'&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='keyglyph'&gt;\&lt;/span&gt;&lt;span class='varid'&gt;p'&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='keyglyph'&gt;[&lt;/span&gt;&lt;span class='keyglyph'&gt;|&lt;/span&gt; &lt;span class='varop'&gt;$&lt;/span&gt;&lt;span class='varid'&gt;p'&lt;/span&gt; &lt;span class='conop'&gt;:&lt;/span&gt; &lt;span class='varop'&gt;$&lt;/span&gt;&lt;span class='varid'&gt;ps'&lt;/span&gt; &lt;span class='keyglyph'&gt;|&lt;/span&gt;&lt;span class='keyglyph'&gt;]&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='varop'&gt;$&lt;/span&gt; &lt;span class='keyword'&gt;case&lt;/span&gt; &lt;span class='varid'&gt;p&lt;/span&gt; &lt;span class='keyword'&gt;of&lt;/span&gt;
        &lt;span class='conid'&gt;SFrag&lt;/span&gt; &lt;span class='varid'&gt;s&lt;/span&gt;  &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='keyglyph'&gt;[&lt;/span&gt;&lt;span class='keyglyph'&gt;|&lt;/span&gt; &lt;span class='varid'&gt;frag&lt;/span&gt; &lt;span class='varop'&gt;$&lt;/span&gt;&lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;litE&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;stringL&lt;/span&gt; &lt;span class='varid'&gt;s&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;         &lt;span class='keyglyph'&gt;|&lt;/span&gt;&lt;span class='keyglyph'&gt;]&lt;/span&gt;
        &lt;span class='conid'&gt;SIFrag&lt;/span&gt; &lt;span class='varid'&gt;s&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='keyglyph'&gt;[&lt;/span&gt;&lt;span class='keyglyph'&gt;|&lt;/span&gt; &lt;span class='varop'&gt;$&lt;/span&gt;&lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;varE&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;mkName&lt;/span&gt; &lt;span class='varid'&gt;s&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;               &lt;span class='keyglyph'&gt;|&lt;/span&gt;&lt;span class='keyglyph'&gt;]&lt;/span&gt;
        &lt;span class='conid'&gt;SIShow&lt;/span&gt; &lt;span class='varid'&gt;s&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='keyglyph'&gt;[&lt;/span&gt;&lt;span class='keyglyph'&gt;|&lt;/span&gt; &lt;span class='varid'&gt;text&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;show&lt;/span&gt; &lt;span class='varop'&gt;$&lt;/span&gt;&lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;varE&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;mkName&lt;/span&gt; &lt;span class='varid'&gt;s&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;   &lt;span class='keyglyph'&gt;|&lt;/span&gt;&lt;span class='keyglyph'&gt;]&lt;/span&gt;
        &lt;span class='conid'&gt;SITxt&lt;/span&gt; &lt;span class='varid'&gt;s&lt;/span&gt;  &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='keyglyph'&gt;[&lt;/span&gt;&lt;span class='keyglyph'&gt;|&lt;/span&gt; &lt;span class='varid'&gt;text&lt;/span&gt; &lt;span class='varop'&gt;$&lt;/span&gt;&lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;varE&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;mkName&lt;/span&gt; &lt;span class='varid'&gt;s&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;          &lt;span class='keyglyph'&gt;|&lt;/span&gt;&lt;span class='keyglyph'&gt;]&lt;/span&gt;
        &lt;span class='conid'&gt;SIRTxt&lt;/span&gt; &lt;span class='varid'&gt;s&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='keyglyph'&gt;[&lt;/span&gt;&lt;span class='keyglyph'&gt;|&lt;/span&gt; &lt;span class='varid'&gt;text&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;render&lt;/span&gt; &lt;span class='varop'&gt;$&lt;/span&gt;&lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;varE&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;mkName&lt;/span&gt; &lt;span class='varid'&gt;s&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='keyglyph'&gt;|&lt;/span&gt;&lt;span class='keyglyph'&gt;]&lt;/span&gt;

&lt;span class='comment'&gt;-- AST for template-specification parts&lt;/span&gt;

&lt;span class='keyword'&gt;data&lt;/span&gt; &lt;span class='conid'&gt;SpecPart&lt;/span&gt;
    &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='conid'&gt;SFrag&lt;/span&gt; &lt;span class='conid'&gt;String&lt;/span&gt;  &lt;span class='comment'&gt;-- ^ language fragment&lt;/span&gt;
    &lt;span class='keyglyph'&gt;|&lt;/span&gt; &lt;span class='conid'&gt;SIFrag&lt;/span&gt; &lt;span class='conid'&gt;String&lt;/span&gt; &lt;span class='comment'&gt;-- ^ insert fragment by variable reference&lt;/span&gt;
    &lt;span class='keyglyph'&gt;|&lt;/span&gt; &lt;span class='conid'&gt;SIShow&lt;/span&gt; &lt;span class='conid'&gt;String&lt;/span&gt; &lt;span class='comment'&gt;-- ^ insert rendered variable via show&lt;/span&gt;
    &lt;span class='keyglyph'&gt;|&lt;/span&gt; &lt;span class='conid'&gt;SITxt&lt;/span&gt; &lt;span class='conid'&gt;String&lt;/span&gt;  &lt;span class='comment'&gt;-- ^ insert literal text variable&lt;/span&gt;
    &lt;span class='keyglyph'&gt;|&lt;/span&gt; &lt;span class='conid'&gt;SIRTxt&lt;/span&gt; &lt;span class='conid'&gt;String&lt;/span&gt; &lt;span class='comment'&gt;-- ^ insert rendered safe string var as text&lt;/span&gt;
  &lt;span class='keyword'&gt;deriving&lt;/span&gt; &lt;span class='conid'&gt;Show&lt;/span&gt;

&lt;span class='comment'&gt;-- Parse a template specification&lt;/span&gt;

&lt;span class='varid'&gt;xparse&lt;/span&gt; &lt;span class='varid'&gt;spec&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='keyword'&gt;do&lt;/span&gt;
    &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;result&lt;/span&gt;&lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='str'&gt;""&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='keyglyph'&gt;&amp;lt;-&lt;/span&gt; &lt;span class='conid'&gt;P&lt;/span&gt;&lt;span class='varop'&gt;.&lt;/span&gt;&lt;span class='varid'&gt;readP_to_S&lt;/span&gt; &lt;span class='varid'&gt;templateP&lt;/span&gt; &lt;span class='varid'&gt;spec&lt;/span&gt;
    &lt;span class='varid'&gt;return&lt;/span&gt; &lt;span class='varid'&gt;result&lt;/span&gt;
 &lt;span class='keyword'&gt;where&lt;/span&gt;
    &lt;span class='varid'&gt;templateP&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='keyword'&gt;do&lt;/span&gt;
        &lt;span class='conid'&gt;P&lt;/span&gt;&lt;span class='varop'&gt;.&lt;/span&gt;&lt;span class='varid'&gt;many&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;liftM&lt;/span&gt; &lt;span class='conid'&gt;SFrag&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='conid'&gt;P&lt;/span&gt;&lt;span class='varop'&gt;.&lt;/span&gt;&lt;span class='varid'&gt;munch1&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varop'&gt;/=&lt;/span&gt; &lt;span class='chr'&gt;'#'&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='conid'&gt;P&lt;/span&gt;&lt;span class='varop'&gt;.&amp;lt;++&lt;/span&gt;
                &lt;span class='varid'&gt;interpolationP&lt;/span&gt; &lt;span class='conid'&gt;P&lt;/span&gt;&lt;span class='varop'&gt;.&amp;lt;++&lt;/span&gt;
                &lt;span class='varid'&gt;liftM&lt;/span&gt; &lt;span class='conid'&gt;SFrag&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='conid'&gt;P&lt;/span&gt;&lt;span class='varop'&gt;.&lt;/span&gt;&lt;span class='varid'&gt;string&lt;/span&gt; &lt;span class='str'&gt;"#"&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;

    &lt;span class='varid'&gt;interpolationP&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='keyword'&gt;do&lt;/span&gt;
        &lt;span class='conid'&gt;P&lt;/span&gt;&lt;span class='varop'&gt;.&lt;/span&gt;&lt;span class='varid'&gt;string&lt;/span&gt; &lt;span class='str'&gt;"#{"&lt;/span&gt;
        &lt;span class='varid'&gt;spec&lt;/span&gt; &lt;span class='keyglyph'&gt;&amp;lt;-&lt;/span&gt; &lt;span class='conid'&gt;P&lt;/span&gt;&lt;span class='varop'&gt;.&lt;/span&gt;&lt;span class='varid'&gt;manyTill&lt;/span&gt; &lt;span class='conid'&gt;P&lt;/span&gt;&lt;span class='varop'&gt;.&lt;/span&gt;&lt;span class='varid'&gt;get&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='conid'&gt;P&lt;/span&gt;&lt;span class='varop'&gt;.&lt;/span&gt;&lt;span class='varid'&gt;char&lt;/span&gt; &lt;span class='chr'&gt;'}'&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
        &lt;span class='varid'&gt;return&lt;/span&gt; &lt;span class='varop'&gt;$&lt;/span&gt; &lt;span class='keyword'&gt;case&lt;/span&gt; &lt;span class='varid'&gt;spec&lt;/span&gt; &lt;span class='keyword'&gt;of&lt;/span&gt;
          &lt;span class='chr'&gt;'r'&lt;/span&gt;&lt;span class='conop'&gt;:&lt;/span&gt;&lt;span class='chr'&gt;' '&lt;/span&gt;&lt;span class='conop'&gt;:&lt;/span&gt;&lt;span class='varid'&gt;var&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;SIRTxt&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;strip&lt;/span&gt; &lt;span class='varid'&gt;var&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
          &lt;span class='chr'&gt;'s'&lt;/span&gt;&lt;span class='conop'&gt;:&lt;/span&gt;&lt;span class='chr'&gt;' '&lt;/span&gt;&lt;span class='conop'&gt;:&lt;/span&gt;&lt;span class='varid'&gt;var&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;SIShow&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;strip&lt;/span&gt; &lt;span class='varid'&gt;var&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
          &lt;span class='chr'&gt;'='&lt;/span&gt;&lt;span class='conop'&gt;:&lt;/span&gt;&lt;span class='varid'&gt;var&lt;/span&gt;     &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;SIFrag&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;strip&lt;/span&gt; &lt;span class='varid'&gt;var&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
          &lt;span class='varid'&gt;var&lt;/span&gt;         &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;SITxt&lt;/span&gt;  &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;strip&lt;/span&gt; &lt;span class='varid'&gt;var&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;

&lt;span class='varid'&gt;strip&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='varid'&gt;frontAndBack&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;dropWhile&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varop'&gt;==&lt;/span&gt; &lt;span class='chr'&gt;' '&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
&lt;span class='varid'&gt;frontAndBack&lt;/span&gt; &lt;span class='varid'&gt;f&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='varid'&gt;reverse&lt;/span&gt; &lt;span class='varop'&gt;.&lt;/span&gt; &lt;span class='varid'&gt;f&lt;/span&gt; &lt;span class='varop'&gt;.&lt;/span&gt; &lt;span class='varid'&gt;reverse&lt;/span&gt; &lt;span class='varop'&gt;.&lt;/span&gt; &lt;span class='varid'&gt;f&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;h3&gt;More sugar: defining additional safe-string types&lt;/h3&gt;


	&lt;p&gt;One additional bit of Template Haskell code, which I won&amp;#8217;t reprint
here, defines &lt;em&gt;declareSafeString&lt;/em&gt;.  This function lets us eliminate
the boilerplate code when defining new safe-string types.  For
example, compare our earlier definition of the SafeXml module with the
following implementation of a module for safe &lt;span class="caps"&gt;URL&lt;/span&gt; strings:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_haskell "&gt;&lt;span class='keyword'&gt;module&lt;/span&gt; &lt;span class='conid'&gt;SafeUrl&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='conid'&gt;Url&lt;/span&gt;&lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='varid'&gt;url&lt;/span&gt;&lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='varid'&gt;renderUrl&lt;/span&gt;&lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='keyword'&gt;module&lt;/span&gt; &lt;span class='conid'&gt;SafeStrings&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='keyword'&gt;where&lt;/span&gt;
&lt;span class='keyword'&gt;import&lt;/span&gt; &lt;span class='conid'&gt;SafeStrings&lt;/span&gt;
&lt;span class='keyword'&gt;import&lt;/span&gt; &lt;span class='conid'&gt;Text&lt;/span&gt;&lt;span class='varop'&gt;.&lt;/span&gt;&lt;span class='conid'&gt;Printf&lt;/span&gt;
&lt;span class='keyword'&gt;import&lt;/span&gt; &lt;span class='conid'&gt;Data&lt;/span&gt;&lt;span class='varop'&gt;.&lt;/span&gt;&lt;span class='conid'&gt;Char&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;ord&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;

&lt;span class='varid'&gt;escapeUrl&lt;/span&gt; &lt;span class='varid'&gt;xs&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt;
    &lt;span class='varid'&gt;concatMap&lt;/span&gt; &lt;span class='varid'&gt;esc&lt;/span&gt; &lt;span class='varid'&gt;xs&lt;/span&gt;
  &lt;span class='keyword'&gt;where&lt;/span&gt;
    &lt;span class='varid'&gt;esc&lt;/span&gt; &lt;span class='varid'&gt;x&lt;/span&gt; &lt;span class='keyglyph'&gt;|&lt;/span&gt; &lt;span class='varid'&gt;isReserved&lt;/span&gt; &lt;span class='varid'&gt;x&lt;/span&gt; &lt;span class='varop'&gt;||&lt;/span&gt; &lt;span class='varid'&gt;x&lt;/span&gt; &lt;span class='varop'&gt;&amp;gt;&lt;/span&gt; &lt;span class='chr'&gt;'~'&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='varid'&gt;urlEncode&lt;/span&gt; &lt;span class='varid'&gt;x&lt;/span&gt;
          &lt;span class='keyglyph'&gt;|&lt;/span&gt; &lt;span class='varid'&gt;x&lt;/span&gt; &lt;span class='varop'&gt;==&lt;/span&gt; &lt;span class='chr'&gt;' '&lt;/span&gt;                &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='str'&gt;"+"&lt;/span&gt;
          &lt;span class='keyglyph'&gt;|&lt;/span&gt; &lt;span class='varid'&gt;otherwise&lt;/span&gt;               &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='keyglyph'&gt;[&lt;/span&gt;&lt;span class='varid'&gt;x&lt;/span&gt;&lt;span class='keyglyph'&gt;]&lt;/span&gt;

&lt;span class='varid'&gt;urlEncode&lt;/span&gt; &lt;span class='varid'&gt;x&lt;/span&gt;  &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='chr'&gt;'%'&lt;/span&gt; &lt;span class='conop'&gt;:&lt;/span&gt; &lt;span class='varid'&gt;printf&lt;/span&gt; &lt;span class='str'&gt;"%02x"&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;ord&lt;/span&gt; &lt;span class='varid'&gt;x&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
&lt;span class='varid'&gt;isReserved&lt;/span&gt;   &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varop'&gt;`elem`&lt;/span&gt; &lt;span class='str'&gt;"!#$&amp;amp;'()*+,/:;=?@[]"&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;

&lt;span class='varop'&gt;$&lt;/span&gt;&lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;declareSafeString&lt;/span&gt; &lt;span class='str'&gt;"url"&lt;/span&gt; &lt;span class='str'&gt;"Url"&lt;/span&gt; &lt;span class='keyglyph'&gt;[&lt;/span&gt;&lt;span class='keyglyph'&gt;|&lt;/span&gt; &lt;span class='varid'&gt;escapeUrl&lt;/span&gt; &lt;span class='keyglyph'&gt;|&lt;/span&gt;&lt;span class='keyglyph'&gt;]&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;The final line generates the boilerplate code for the wrapper type,
the language definition, the &lt;em&gt;Url&lt;/em&gt; type synonym, and the &lt;em&gt;url&lt;/em&gt; and
&lt;em&gt;renderUrl&lt;/em&gt; language-specific convenience functions.&lt;/p&gt;


	&lt;h3&gt;One big example to wrap things up&lt;/h3&gt;


	&lt;p&gt;Because we have been discussing mainly library code, let&amp;#8217;s take a step
back and see some typical user-level code that uses safe strings.
After all, that&amp;#8217;s what counts.&lt;/p&gt;


	&lt;p&gt;Here is a Haskellized, safe-strings version of the Ruby (on Rails)
code that I presented at the beginning of the article to add
submit-to-Reddit and submit-to-del.icio.us buttons to my blog:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_haskell "&gt;&lt;span class='keyword'&gt;module&lt;/span&gt; &lt;span class='conid'&gt;Example&lt;/span&gt; &lt;span class='keyword'&gt;where&lt;/span&gt;
&lt;span class='keyword'&gt;import&lt;/span&gt; &lt;span class='conid'&gt;List&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;intersperse&lt;/span&gt;&lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='varid'&gt;break&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
&lt;span class='keyword'&gt;import&lt;/span&gt; &lt;span class='conid'&gt;SafeXml&lt;/span&gt;
&lt;span class='keyword'&gt;import&lt;/span&gt; &lt;span class='conid'&gt;SafeUrl&lt;/span&gt;

&lt;span class='keyword'&gt;type&lt;/span&gt; &lt;span class='conid'&gt;Xhtml&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='conid'&gt;Xml&lt;/span&gt;

&lt;span class='varid'&gt;submit_this_article_links&lt;/span&gt; &lt;span class='keyglyph'&gt;::&lt;/span&gt; &lt;span class='conid'&gt;Article&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;Xhtml&lt;/span&gt;
&lt;span class='varid'&gt;submit_this_article_links&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='conid'&gt;Article&lt;/span&gt; &lt;span class='varid'&gt;title&lt;/span&gt; &lt;span class='varid'&gt;url&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt;
    &lt;span class='varid'&gt;cat&lt;/span&gt; &lt;span class='varop'&gt;.&lt;/span&gt; &lt;span class='varid'&gt;intersperse&lt;/span&gt; &lt;span class='varid'&gt;nbsp&lt;/span&gt; &lt;span class='varop'&gt;$&lt;/span&gt; &lt;span class='keyword'&gt;do&lt;/span&gt;
    &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;submit_title&lt;/span&gt;&lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='varid'&gt;submit_url&lt;/span&gt; &lt;span class='keyglyph'&gt;::&lt;/span&gt; &lt;span class='conid'&gt;Url&lt;/span&gt;&lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='varid'&gt;image_tag&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='keyglyph'&gt;&amp;lt;-&lt;/span&gt; &lt;span class='varid'&gt;site_list&lt;/span&gt;
    &lt;span class='varid'&gt;return&lt;/span&gt; &lt;span class='varop'&gt;$&lt;/span&gt;&lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;q&lt;/span&gt;
      &lt;span class='str'&gt;"&amp;lt;a href=\"#{r submit_url}\" \
         \title=\"#{submit_title}: &amp;amp;#x201C;#{title}&amp;amp;#x201D;\" \
        \&amp;gt;#{=image_tag}&amp;lt;/a&amp;gt;"&lt;/span&gt; &lt;span class='layout'&gt;)&lt;/span&gt;

  &lt;span class='keyword'&gt;where&lt;/span&gt;

    &lt;span class='varid'&gt;nbsp&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='varid'&gt;xml&lt;/span&gt; &lt;span class='str'&gt;"&amp;amp;#160;"&lt;/span&gt;

    &lt;span class='varid'&gt;site_list&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='keyglyph'&gt;[&lt;/span&gt;  &lt;span class='comment'&gt;-- move me into a database table&lt;/span&gt;
      &lt;span class='layout'&gt;(&lt;/span&gt; &lt;span class='str'&gt;"Submit to Reddit.com"&lt;/span&gt;
      &lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='varop'&gt;$&lt;/span&gt;&lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;q&lt;/span&gt; &lt;span class='str'&gt;"http://reddit.com/submit?url=#{r url}&amp;amp;title=#{title}"&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
      &lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='varid'&gt;image_tag&lt;/span&gt; &lt;span class='str'&gt;"reddit.gif"&lt;/span&gt; &lt;span class='str'&gt;"18x18"&lt;/span&gt; &lt;span class='num'&gt;0&lt;/span&gt;
      &lt;span class='layout'&gt;)&lt;/span&gt;&lt;span class='layout'&gt;,&lt;/span&gt;
      &lt;span class='layout'&gt;(&lt;/span&gt; &lt;span class='str'&gt;"Save to del.icio.us"&lt;/span&gt;
      &lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='varop'&gt;$&lt;/span&gt;&lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;q&lt;/span&gt; &lt;span class='str'&gt;"http://del.icio.us/post?v=2&amp;amp;url=#{r url}&amp;amp;title=#{title}"&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
      &lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='varid'&gt;image_tag&lt;/span&gt; &lt;span class='str'&gt;"delicious.gif"&lt;/span&gt; &lt;span class='str'&gt;"16x16"&lt;/span&gt; &lt;span class='num'&gt;0&lt;/span&gt;
      &lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='keyglyph'&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The code looks fairly similar to the original Ruby code, with the exception
of some extra backslashes, courtesy of Haskell&amp;#8217;s rather-unfortunate
syntax for multi-line string constants. (Perl and Ruby&amp;#8217;s
&lt;code&gt;&amp;lt;&amp;lt;HERE&lt;/code&gt; syntax would be a welcome addition.)&lt;/p&gt;

	&lt;p&gt;The other big difference is that, in this version, the type system has
automatically checked the code for strings-problem errors.&lt;/p&gt;


	&lt;p&gt;For completeness, here is the example&amp;#8217;s supporting code (again modeled
on Ruby on Rails).  This code also makes
extensive use of safe-string templates:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_haskell "&gt;&lt;span class='varid'&gt;image_tag&lt;/span&gt; &lt;span class='keyglyph'&gt;::&lt;/span&gt; &lt;span class='conid'&gt;String&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;String&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;Int&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;Xhtml&lt;/span&gt;
&lt;span class='varid'&gt;image_tag&lt;/span&gt; &lt;span class='varid'&gt;file_name&lt;/span&gt; &lt;span class='varid'&gt;size&lt;/span&gt; &lt;span class='varid'&gt;border&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt;
    &lt;span class='varop'&gt;$&lt;/span&gt;&lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;q&lt;/span&gt; &lt;span class='str'&gt;"&amp;lt;img src=\"#{r image_url}\" height=\"#{height}\" \
         \width=\"#{width}\" border=\"#{s border}\"/&amp;gt;"&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
  &lt;span class='keyword'&gt;where&lt;/span&gt;
    &lt;span class='varid'&gt;image_url&lt;/span&gt;         &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='varop'&gt;$&lt;/span&gt;&lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;q&lt;/span&gt; &lt;span class='str'&gt;"#{=site_root}images/#{file_name}"&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;
    &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;width&lt;/span&gt;&lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='keyword'&gt;_&lt;/span&gt;&lt;span class='conop'&gt;:&lt;/span&gt;&lt;span class='varid'&gt;height&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='varid'&gt;break&lt;/span&gt; &lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varop'&gt;==&lt;/span&gt;&lt;span class='chr'&gt;'x'&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt; &lt;span class='varid'&gt;size&lt;/span&gt;

&lt;span class='varid'&gt;link_to&lt;/span&gt; &lt;span class='keyglyph'&gt;::&lt;/span&gt; &lt;span class='conid'&gt;Xhtml&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;Url&lt;/span&gt; &lt;span class='keyglyph'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='conid'&gt;Xhtml&lt;/span&gt;
&lt;span class='varid'&gt;link_to&lt;/span&gt; &lt;span class='varid'&gt;content&lt;/span&gt; &lt;span class='varid'&gt;url&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt;
    &lt;span class='varop'&gt;$&lt;/span&gt;&lt;span class='layout'&gt;(&lt;/span&gt;&lt;span class='varid'&gt;q&lt;/span&gt; &lt;span class='str'&gt;"&amp;lt;a href=\"#{r url}\"&amp;gt;#{=content}&amp;lt;/a&amp;gt;"&lt;/span&gt;&lt;span class='layout'&gt;)&lt;/span&gt;

&lt;span class='keyword'&gt;data&lt;/span&gt; &lt;span class='conid'&gt;Article&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt; &lt;span class='conid'&gt;Article&lt;/span&gt;
  &lt;span class='layout'&gt;{&lt;/span&gt; &lt;span class='varid'&gt;article_title&lt;/span&gt;  &lt;span class='keyglyph'&gt;::&lt;/span&gt; &lt;span class='conid'&gt;String&lt;/span&gt;
  &lt;span class='layout'&gt;,&lt;/span&gt; &lt;span class='varid'&gt;article_url&lt;/span&gt;    &lt;span class='keyglyph'&gt;::&lt;/span&gt; &lt;span class='conid'&gt;Url&lt;/span&gt;
    &lt;span class='comment'&gt;-- more fields here&lt;/span&gt;
  &lt;span class='layout'&gt;}&lt;/span&gt;

&lt;span class='varid'&gt;sample_article&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt;
    &lt;span class='conid'&gt;Article&lt;/span&gt; &lt;span class='str'&gt;"I love chunky bacon!"&lt;/span&gt; &lt;span class='varop'&gt;$&lt;/span&gt;
    &lt;span class='varid'&gt;url&lt;/span&gt; &lt;span class='str'&gt;"http://blog.moertel.com/permalink/to/article"&lt;/span&gt;

&lt;span class='varid'&gt;site_root&lt;/span&gt; &lt;span class='keyglyph'&gt;::&lt;/span&gt; &lt;span class='conid'&gt;Url&lt;/span&gt;
&lt;span class='varid'&gt;site_root&lt;/span&gt; &lt;span class='keyglyph'&gt;=&lt;/span&gt;  &lt;span class='varid'&gt;url&lt;/span&gt; &lt;span class='str'&gt;"http://blog.moertel.com/"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;h3&gt;Have we done it?  Have we learned anything?&lt;/h3&gt;


	&lt;p&gt;Have we rid ourselves of the strings problem?  If we use a programming
language like Haskell and a library like SafeStrings, I think we can
answer yes.&lt;/p&gt;


	&lt;p&gt;To be clear, the fundamental problem of having to manage different
kinds of strings is still with us.  As programmers, we still must
understand the differences between URLs, &lt;span class="caps"&gt;XML&lt;/span&gt;, SQL, untrusted user
input, and so on.  But now, we don&amp;#8217;t have to be perfect.  As long as
we can reliably slap the right type on a string when it first appears,
we can let the computer worry about it from then on.  If we forget to
escape the string later, as it winds its way through the twisty code
of a large web application and interacts with other strings in
potentially dangerous ways, the computer will catch our mistake &amp;#8211; at
compile time, before it can possibly become a live security hole.&lt;/p&gt;


	&lt;p&gt;But if slapping the right types on strings &amp;#8211; certifying them &amp;#8211; is a
pain in the neck, we won&amp;#8217;t do it.  We will happily go back to our days
of winging it, where every string interaction becomes an opportunity
for a perfectly human mistake to give birth to a nasty security
vulnerability.&lt;/p&gt;


	&lt;p&gt;That&amp;#8217;s why syntax matters.  That&amp;#8217;s why Template Haskell, Lisp macros,
and other meta-programming tools are important: they let us craft
friendly syntaxes that encourage the use of programming aids like
SafeStrings.  That&amp;#8217;s why type inferencing is important: it lets us do
away with redundant annotations and makes working with types
convenient, so we can reap the benefits of strong guarantees without
having to pay prohibitive costs.&lt;/p&gt;


	&lt;p&gt;If there is a moral to this story, it&amp;#8217;s that modern type systems and
macro systems are powerful tools.  They let us do things that
otherwise would be impractically inconvenient.  They extend our reach
as programmers and let us solve problems that we couldn&amp;#8217;t solve
before.  Why, then, do so many programmers dismiss these tools
as mere academic curiosities?  Why do so many programmers turn away to
fight unaided against, and frequently lose to, the very problems that
these tools could so easily solve?&lt;/p&gt;


&lt;div class="update"&gt;
&lt;strong&gt;Update:&lt;/strong&gt; minor edits for clarity.
&lt;/div&gt;</description>
      <pubDate>Wed, 18 Oct 2006 21:40:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:4a7fb02b-a1ba-4c4a-a63b-938a19f3076c</guid>
      <author>Tom Moertel</author>
      <link>http://blog.moertel.com/articles/2006/10/18/a-type-based-solution-to-the-strings-problem</link>
      <category>programming</category>
      <category>programming languages</category>
      <category>haskell</category>
      <category>ruby</category>
      <category>web development</category>
      <category>testing</category>
      <category>rails</category>
      <category>ruby</category>
      <category>haskell</category>
      <category>testing</category>
      <category>strings</category>
      <category>types</category>
      <trackback:ping>http://blog.moertel.com/articles/trackback/186</trackback:ping>
    </item>
    <item>
      <title>Ryan Carson: Building web applications on a budget</title>
      <description>&lt;p&gt;Via &lt;a href="http://simon.incutio.com/archive/2006/02/08/summit"&gt;Simon Willison&amp;#8217;s post&lt;/a&gt; about the &lt;a href="http://www.carsonworkshops.com/summit/"&gt;2006 Future of Web Apps Summit&lt;/a&gt;, I found &lt;a href="http://simon.incutio.com/notes/2006/summit/carson.txt"&gt;notes for Ryan Carson&amp;#8217;s talk about building web apps on a budget&lt;/a&gt;.
In the talk Ryan breaks down the budget for starting up &lt;a href="http://www.dropsend.com/"&gt;DropSend&lt;/a&gt;:&lt;/p&gt;


	&lt;table&gt;
		&lt;tr&gt;
			&lt;th style="text-align:right;"&gt;Budget (£) &lt;/th&gt;
			&lt;th&gt;Need &lt;/th&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td style="text-align:right;"&gt;5,000 &lt;/td&gt;
			&lt;td&gt; Branding &amp;#38; UI design &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td style="text-align:right;"&gt;8,500 &lt;/td&gt;
			&lt;td&gt; Development of web app (developers also given small equity stake) &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td style="text-align:right;"&gt;2,750 &lt;/td&gt;
			&lt;td&gt; Desktop apps (Windows and Mac) &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td style="text-align:right;"&gt;1,600 &lt;/td&gt;
			&lt;td&gt; Building &lt;span class="caps"&gt;XHTML&lt;/span&gt;/CSS &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td style="text-align:right;"&gt;500 &lt;/td&gt;
			&lt;td&gt; Hardware (internal development server) &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td style="text-align:right;"&gt;800 &lt;/td&gt;
			&lt;td&gt; (per month) hosting and maintenance &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td style="text-align:right;"&gt;2,630&lt;/td&gt;
			&lt;td&gt; Legal fees &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td style="text-align:right;"&gt;500 &lt;/td&gt;
			&lt;td&gt; Accounting fees &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td style="text-align:right;"&gt;500 &lt;/td&gt;
			&lt;td&gt; Linux-specialist fees &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td style="text-align:right;"&gt;1,950 &lt;/td&gt;
			&lt;td&gt; Misc. fees (trips, replace broken hardware) &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td style="text-align:right;"&gt;250 &lt;/td&gt;
			&lt;td&gt; Trademark &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td style="text-align:right;"&gt;200 &lt;/td&gt;
			&lt;td&gt; Merchant account &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td style="text-align:right;"&gt;500 &lt;/td&gt;
			&lt;td&gt; Payment processor&amp;#8217;s setup fee &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td style="text-align:right;"&gt;&lt;strong&gt;25,680&lt;/strong&gt; &lt;/td&gt;
			&lt;td&gt; &lt;strong&gt;Total&lt;/strong&gt; &lt;/td&gt;
		&lt;/tr&gt;
	&lt;/table&gt;




	&lt;p&gt;That is about $45K in US dollars. In other words, you can launch a new web application for less than a skilled technology worker&amp;#8217;s salary.  Or, if you &lt;em&gt;are&lt;/em&gt; a skilled technology worker, you can do much of the work yourself and launch a new web application for about $25K.&lt;/p&gt;


	&lt;p&gt;Got an itch to scratch?&lt;/p&gt;</description>
      <pubDate>Wed, 08 Feb 2006 14:25:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:2839974db1df97754c7f2454301694c4</guid>
      <author>Tom Moertel</author>
      <link>http://blog.moertel.com/articles/2006/02/08/ryan-carson-building-web-applications-on-a-budget</link>
      <category>web development</category>
      <category>business</category>
      <trackback:ping>http://blog.moertel.com/articles/trackback/52</trackback:ping>
    </item>
    <item>
      <title>A simple Apache recipe for migrating blog articles to a new host</title>
      <description>&lt;p&gt;In &lt;a href="http://blog.moertel.com/articles/2006/01/21/everything-old-is-new-again-moving-content-over-from-my-old-blog"&gt;Everything old is new
again&lt;/a&gt;,
I wrote that I was moving articles from my old blog over to my new
Typo-powered blog (here).  Now that the process is underway, I need to
make sure that people looking for my old articles can find them at
their new home.  To solve this problem, I am using a simple Apache httpd
recipe to redirect requests for the old articles to the corresponding
updated articles on my new blog.  In case you need to do something
similar some day, here is the recipe.&lt;/p&gt;


	&lt;h3&gt;First, set up a mapping file&lt;/h3&gt;


	&lt;p&gt;Create a two-column mapping file that you can use to map each
article&amp;#8217;s old location to its corresponding new location.  If there
are any parts of the locations that never change, you can factor them
out to reduce clutter.&lt;/p&gt;


	&lt;p&gt;For example, the article &amp;#8220;My New Radio &lt;span class="caps"&gt;VCR&lt;/span&gt;&amp;#8221; has the following old and
new locations (the constant parts are emphasized):&lt;/p&gt;


	&lt;table style="background: #eee; margin-bottom: 2ex;"&gt;
		&lt;tr&gt;
			&lt;td&gt; Old &lt;/td&gt;
			&lt;td&gt; = &lt;strong&gt;http://community.moertel.com/ss/space&lt;/strong&gt;/2004-02-20  &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt; New &lt;/td&gt;
			&lt;td&gt; = &lt;strong&gt;http://blog.moertel.com/&lt;/strong&gt;articles/2004/02/20/my-new-radio-vcr &lt;/td&gt;
		&lt;/tr&gt;
	&lt;/table&gt;




	&lt;p&gt;Its entry in my mapping file looks like this:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;# File: /path/to/conf/old-blog-to-new.txt
# Map articles from old blog to new blog.
#
# OLD LOCATION    NEW LOCATION
# .../ss/space/X  http://blog.moertel.com/Y

...               ...
2004-02-20        articles/2004/02/20/my-new-radio-vcr
...               ...
&lt;/code&gt;&lt;/pre&gt;

	&lt;h3&gt;Second, configure Apache to use the mapping file&lt;/h3&gt;


	&lt;p&gt;Edit the Apache configuration that controls the old locations.
Add a set of 
&lt;a href="http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html"&gt;mod_rewrite&lt;/a&gt; rules to
match requests for the old locations and redirect them to the
corresponding new locations, using the mapping file as a reference.  For example,
here is my configuration:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;# in Apache's configuration for community.moertel.com

RewriteEngine on
RewriteMap blogmap txt:/path/to/conf/old-blog-to-new.txt
RewriteCond ${blogmap:$1|NOT-FOUND} !=NOT-FOUND
RewriteRule ^/ss/space/(.+) http://blog.moertel.com/${blogmap:$1} [R=301,L]
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;The first line makes sure that mod_rewrite is active.&lt;/p&gt;


	&lt;p&gt;The second line tells Apache to load the mapping file.  Apache will
cache the mapping file&amp;#8217;s contents for speed, but it is smart enough to
reload the file when modified.  That means you can add new entries to
the mapping file at any time, and Apache will act on them immediately,
no restart or reload required.  Every time I moved an article over to
the new blog, for example, I just edited the mapping file, and the new
location &amp;#8220;went live,&amp;#8221; replacing the old.&lt;/p&gt;


	&lt;p&gt;The third line says that the recipe is conditional upon
there being a matching entry in the mapping file.  If no entry
exists, the recipe will not apply, and the request will be handled
as usual.&lt;/p&gt;


&lt;p&gt;The final line defines the rewrite rule.  In this example, it tries
to match requests that start with &amp;#8221;/ss/space/&lt;em&gt;X_&amp;#8221;, where _X&lt;/em&gt; is any
suffix. (The prefix &amp;#8220;http://community.moertel.com&amp;#8221; is implied because
this configuration is for the community.moertel.com site.) If the
request matches, &lt;em&gt;X&lt;/em&gt; is stored in the &lt;code&gt;$1&lt;/code&gt; variable.
Then &amp;#8211; and this is one of those things that makes mod_rewrite seem
tricky &amp;#8211; the condition defined in the &lt;em&gt;previous&lt;/em&gt; line is tested using the current
value of &lt;code&gt;$1&lt;/code&gt;.  If the condition is satisfied, the request
is redirected to http://blog.moertel.com/&lt;em&gt;Y_, where _Y&lt;/em&gt; is the
corresponding location for &lt;em&gt;X&lt;/em&gt;, according to the mapping file.&lt;/p&gt;

	&lt;p&gt;The &lt;code&gt;[R=301,L]&lt;/code&gt; part of the rewrite rule is important.  It
specifies that redirects should be of the 301-Permanent variety.  This
advertises to the world that the new locations are intended to
&lt;em&gt;replace&lt;/em&gt; the old locations.  Using permanent redirects also ensures
that any &lt;a href="http://en.wikipedia.org/wiki/Google_juice"&gt;Google juice&lt;/a&gt; that
may have accumulated for my articles follows them to their new
home.&lt;/p&gt;


	&lt;h3&gt; Third, activate the new configuration&lt;/h3&gt;


	&lt;p&gt;This part is easy:  restart Apache to make sure it turns on the
rewrite engine and activates the new configuration directives.&lt;/p&gt;


	&lt;h3&gt; Finally, test it out&lt;/h3&gt;


	&lt;p&gt;To see if everything is working properly, visit an article&amp;#8217;s
old location to see if you are redirected to the corresponding
new location.  For example:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://community.moertel.com/ss/space/2004-02-20"&gt;http://community.moertel.com/ss/space/2004-02-20&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;If you click on this link, you should be redirected to blog.moertel.com.&lt;/p&gt;


	&lt;p&gt;And that&amp;#8217;s the recipe.&lt;/p&gt;</description>
      <pubDate>Mon, 06 Feb 2006 17:52:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:e15c26dc481101280414328cf179e6b0</guid>
      <author>Tom Moertel</author>
      <link>http://blog.moertel.com/articles/2006/02/06/a-simple-apache-recipe-for-migrating-blog-articles-to-a-new-host</link>
      <category>site news</category>
      <category>web development</category>
      <trackback:ping>http://blog.moertel.com/articles/trackback/51</trackback:ping>
    </item>
    <item>
      <title>Top-ten weblog usability mistakes: My blog's scorecard</title>
      <description>&lt;p&gt;Jakob Nielsen&amp;#8217;s Alertbox for 17 October 2005
is &lt;a href="http://www.useit.com/alertbox/weblogs.html"&gt;Weblog Usability: The Top Ten Design Mistakes&lt;/a&gt;.  In other words, it&amp;#8217;s a top-ten list of things &lt;em&gt;not&lt;/em&gt; to do on your blog if you care about usability.&lt;/p&gt;


	&lt;p&gt;Since I care about usability, I decided to test my own weblog against
Jakob&amp;#8217;s top-ten list.  How did I fare?&lt;/p&gt;


	&lt;p&gt;Let&amp;#8217;s see:&lt;/p&gt;


&lt;div style="text-align: center; width:100%"&gt;Top Ten Weblog Usability Mistakes&lt;/div&gt;

&lt;ol&gt;

&lt;li&gt;&lt;strong&gt;No author biography: &lt;em&gt;Fail&lt;/em&gt;.&lt;/strong&gt; Oops, got me there.  While I have a &lt;a href="http://community.moertel.com/ss/space/tmoertel"&gt;bio on
the Community Projects site&lt;/a&gt;,
I don&amp;#8217;t even link to it from my blog.&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;No author photo: &lt;em&gt;Fail&lt;/em&gt;.&lt;/strong&gt; Oops, again.  I don&amp;#8217;t have a photo of myself on
the blog, nor on any other site (that I know of).&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;Nondescript posting titles: &lt;em&gt;Pass&lt;/em&gt;.&lt;/strong&gt; I generally give my posts
informative titles such as
&lt;a href="http://community.moertel.com/ss/space/start/2005-08-22/1#How_to_change_symlinks_atomically"&gt;How to change symlinks atomically&lt;/a&gt;
and
&lt;a href="http://community.moertel.com/ss/space/start/2005-08-10/1#Simple_data_formats_are_not_going_away"&gt;Simple data formats are not going away&lt;/a&gt;.
Only rarely do I use cutesy
titles such as
&lt;a href="http://community.moertel.com/ss/space/start/2005-08-24/1#On_the_effortless_cultivation_of_humility"&gt;On the effortless cultivation of humility&lt;/a&gt;, where readers are forced
to guess what the post is about.&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;Links don&amp;#8217;t say where they go: &lt;em&gt;Pass&lt;/em&gt;.&lt;/strong&gt; As a reader, I find &amp;#8220;click
&lt;em&gt;here&lt;/em&gt;&amp;#8221; links to be annoying, and so I avoid the practice in my writing.&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;Classic hits are buried: &lt;em&gt;Pass&lt;/em&gt;.&lt;/strong&gt; I link to popular topics in the
&lt;em&gt;Popular Topics&lt;/em&gt; sidebar.&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;The calendar is the only navigation: &lt;em&gt;Pass&lt;/em&gt;.&lt;/strong&gt;  My posts are organized by topic as well as by date.  Further, the ever-present live search makes finding posts by content easy.&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;Irregular publishing frequency: &lt;em&gt;Fail&lt;/em&gt;.&lt;/strong&gt;  I don&amp;#8217;t have a regular posting schedule.  When work gets heavy, for example, I rarely post.&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;Mixing topics: &lt;em&gt;Semi-Pass&lt;/em&gt;.&lt;/strong&gt;  I do mix up topics somewhat, but almost all of my topics fall into the category of &amp;#8220;stuff programming geeks like&amp;#8221; and in that regard are fairly consistent.&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;Forgetting that you write for your future boss: &lt;em&gt;Pass&lt;/em&gt;.&lt;/strong&gt; I don&amp;#8217;t think there is anything on my blog that a future employer would find troubling or even unprofessional.  (Since I am a consultant, I have lots of &amp;#8220;employers,&amp;#8221; and so far none of them seem to mind what I post.  Some &amp;#8211; the crazy ones &amp;#8211; even enjoy my blog.)&lt;/li&gt;

&lt;li&gt;&lt;strong&gt;Having a domain name owned by a weblog service: &lt;em&gt;Pass&lt;/em&gt;.&lt;/strong&gt;  Since 1996 I have been keeping it real on &lt;em&gt;moertel.com.&lt;/em&gt;  My blog&amp;#8217;s home is &lt;a href="http://blog.moertel.com"&gt;blog.moertel.com&lt;/a&gt;, which seems like the natural place for it.&lt;/li&gt;

&lt;/ol&gt;

	&lt;p&gt;In sum, I made three of Jakob&amp;#8217;s top-ten weblog usability mistakes:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;I don&amp;#8217;t have an author bio.&lt;/li&gt;
		&lt;li&gt;I don&amp;#8217;t have an author photo.&lt;/li&gt;
		&lt;li&gt;I don&amp;#8217;t post regularly.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;The first two are easy to fix, and I&amp;#8217;ll fix them right away.  The
third &amp;#8211; posting regularly &amp;#8211; is more difficult, owing to the
ever-varying demands of my work load, but I&amp;#8217;ll make an effort to pick
up the pace.  Hopefully, my blog will 100 percent &amp;#8220;Jakob compliant&amp;#8221; 
in the next day or so.&lt;/p&gt;


	&lt;p&gt;Do you have a weblog?  If so, how many weblog usability mistakes do
you make?  Grab &lt;a href="http://www.useit.com/alertbox/weblogs.html"&gt;Jakob&amp;#8217;s top-ten list&lt;/a&gt; and find out.&lt;/p&gt;</description>
      <pubDate>Wed, 26 Oct 2005 16:51:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:d52e7d0d9b16b1546b5b3ada4d0fdf29</guid>
      <author>Tom Moertel</author>
      <link>http://blog.moertel.com/articles/2005/10/26/top-ten-weblog-usability-mistakes-my-blogs-scorecard</link>
      <category>site news</category>
      <category>web development</category>
      <category>usability</category>
      <trackback:ping>http://blog.moertel.com/articles/trackback/9</trackback:ping>
    </item>
    <item>
      <title>Google Web Accelerator vs. unsafe linking: Round Two!</title>
      <description>&lt;p&gt;The good folks at &lt;a href="http://37signals.com"&gt;37signals&lt;/a&gt; are once again up
in arms about &lt;a href="http://webaccelerator.google.com/"&gt;Google Web
Accelerator&lt;/a&gt; (GWA).  David
Heinemeier Hansson (DHH), in particular, writes in a recent post to
&lt;a href="http://37signals.com/svn/"&gt;Signal vs. Noise&lt;/a&gt; that &amp;#8220;[GWA] was evil
enough the first time around, but this time it&amp;#8217;s downright scary.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;The problem, it seems, is that &lt;span class="caps"&gt;GWA&lt;/span&gt; automatically, silently, and
unblockably follows hypertext links to web pages that are linked to by
the pages you visit.  It does this in order to cache those pages so
that if you visit them later, it will have cached copies ready in an
instant, thus &amp;#8220;accelerating&amp;#8221; your web surfing.  But some web
developers use hypertext links to trigger potentially unsafe actions,
such as deleting records in a database, and when &lt;span class="caps"&gt;GWA&lt;/span&gt; automatically
follows such links, it triggers the actions.&lt;/p&gt;


	&lt;p&gt;Oops.&lt;/p&gt;


	&lt;h3&gt;Let&amp;#8217;s do the time warp again&amp;#8230;&lt;/h3&gt;


	&lt;p&gt;Now, if this story sounds familiar, that&amp;#8217;s because half a year
ago, the exact same thing happened.  &lt;span class="caps"&gt;GWA&lt;/span&gt; was unveiled to the public.
People started using it.  And some of those people started losing data
from their accounts with popular web applications, such as
37signal&amp;#8217;s own &lt;a href="http://www.backpackit.com/"&gt;Backpack&lt;/a&gt;.  37signals
&lt;a href="http://37signals.com/svn/archives2/google_web_accelerator_hey_not_so_fast_an_alert_for_web_app_designers.php"&gt;publicized the problem in their blog&lt;/a&gt; and &lt;span class="caps"&gt;DHH&lt;/span&gt; even
&lt;a href="http://www.loudthinking.com/arc/000454.html"&gt;called for a recall on &lt;span class="caps"&gt;GWA&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;And then the community responses came in.  For the most part, the
responses could be divided into two camps, based on who was
blamed for the problem. The first camp blamed the web designers who used
links to trigger unsafe actions (in violation of applicable standards),
and the second camp blamed Google for unleashing &lt;span class="caps"&gt;GWA&lt;/span&gt; upon a web where
standards aren&amp;#8217;t always followed.&lt;/p&gt;


	&lt;p&gt;Both viewpoints had some merit, but I was in the first camp and thus
argued for following the standards and against unsafe linking
practices:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://community.moertel.com/ss/space/start/2005-05-06/1#Google_Web_Accelerator_offers_web_developers_an_important_opportunity"&gt;Google Web Accelerator offers web developers an important opportunity&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://community.moertel.com/ss/space/start/2005-05-08/1"&gt;Taking the unsafe GETs out of Rails&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;What surprised me was that so many people in the second camp argued in
defense of unsafe linking practices, which I had thought indefensible.
I didn&amp;#8217;t have any problem with arguments against Google&amp;#8217;s unleashing
&lt;span class="caps"&gt;GWA&lt;/span&gt; on an imperfect web, but arguing &lt;em&gt;for&lt;/em&gt; the web&amp;#8217;s imperfections
seemed like an odd way of making the case.  The supportive arguments
boiled down to the following:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Lots of web sites use action-triggering links, so the practice is &lt;em&gt;de facto&lt;/em&gt; acceptable.&lt;/li&gt;
		&lt;li&gt;The existing palette of user-interface options is too limited for today&amp;#8217;s web applications; thus, designers are justified in breaking the rules.&lt;/li&gt;
		&lt;li&gt;The standards don&amp;#8217;t actually prohibit the practice (they say &amp;#8220;SHOULD &lt;span class="caps"&gt;NOT&lt;/span&gt;,&amp;#8221; not &amp;#8220;MUST &lt;span class="caps"&gt;NOT&lt;/span&gt;&amp;#8221;); thus, the practice is allowable.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;None of the arguments seem to withstand scrutiny.  The first argument
breaks down like so: That lots of web sites do it only means that
those sites get away with it, not that the practice is acceptable.
Further, as &lt;span class="caps"&gt;GWA&lt;/span&gt; demonstrates, those sites may not get away with the
practice much longer.&lt;/p&gt;


	&lt;p&gt;The second argument breaks down when one examines the uses of unsafe
linking practices.  Most of them could be replaced by safe practices
through modest UI refactoring.  Given that safe alternatives exist,
the unsafe practices are