Scheme Quasistring
Unleash your inner Perl programmer!
Introduction
In perl, when a double-quoted string contains a variable identifier,
Perl substitutes a string representation of that variable's current
binding at the time the string is evaluated. So, for instance, in a
context in which $name
was bound to the string 'Jacob',
the source code fragment "Hello
my name is $name" would evaluate to the string datum 'Hello my name is Jacob'.
Scheme Quasistring adds this ability to PLT Scheme and goes one better.
When using the quasistring library, s-expressions following a
dollar-sign symbol are read and interpreted as expressions in the
surrounding environment. This allows Perl-style string variables as a
special case, and arbitrary computation within strings in general. For
instance,
(let ((name "Jacob")) (qs "Hello
my name is $name"))
evaluates to "Hello my name is Jacob" as expected, and so does
(let ((name "Jacob")) (qs "Hello
my name is $((lambda (x) x) name)"))
or
(let ((name '(b o c a)))
(qs "Hello my name is J$(apply string-append (reverse (map
symbol->string name)))"))
or any number of other computations. Quasistring is integrated
with DrScheme: errors in quasistrings will be reported correctly, the
check-syntax tool will correctly color and draw arrows to and from
quasistring expressions, and the profiler and flow-analysis tools will
understand the quasistring forms properly. Here are a few screenshots
of quasistring in action:

This screenshot demonstrates basic use and shows that DrScheme's
check-syntax tool properly colors and assigns arrows to expressions
within quasistrings.

This screenshot demonstrates that DrScheme properly highlights errors
within quasistrings. Though not pictured, backtrace also works.
Installing Quasistring
To install the quasistring library, take the following steps:
- In DrScheme, select File
-> Install .plt File ... and select the "Web" tab.
- Paste this URL: http://people.cs.uchicago.edu/~jacobm/qstr/quasistring.plt
into the URL box and click OK.
This should install quasistring on your system.
Using Quasistring
With quasistring installed, you will have access to a new collection
called quasistring that contains two libraries, quasistring.ss and qstr-lang.ss. They are
described here separately.
quasistring.ss - the basic quasistring package
To use: (require (lib
"quasistring.ss" "quasistring"))
quasistring.ss provides
two names: qs and current-quasistring-converter.
qs
(qs str) -> str
qs requires a syntactic string as its argument.
qs evaluates to the syntactic string it was provided, but with any
occurrences of a dollar-sign followed by an s-expression in the string
replaced by the evaluation of that s-expression in the current lexical
context and converted to a string with display (or by applying the
value of the current-quasistring-converter
parameter to it).
Literal dollar signs can be included in quasistrings by escaping using
a double-backslash.
Quasistring strings preserve eq-ness across multiple evaluations of the
same quasistring if the template string contains no s-expressions.
current-quasistring-converter
current-quasistring-converter is a parameter that accepts any Scheme
value and prints a character representation of it. The qs macro uses this parameter to
convert values to string form; its default value is the mzscheme display procedure.
qstr-lang.ss - the quasistring language
To use: (module mymodule (lib "qstr-lang.ss" "quasistring")
...)
qstr-lang.ss is a
wrapper
for quasistring.ss
intended to be used as a module language (i.e., an alternative to mzscheme when specifying a
module). All strings in modules written in qstr-lang.ss are quasistrings;
the qs macro is not
required (nor is it provided). The current-quasistring-converter
parameter works as expected.
Known Problems
By necessity, the quasistring library uses an approximation of the
source location for the expressions inside a quasistring. This
approximation assumes that programmers will use the smallest character
representation of any particular character that appears in source code;
for instance, it assumes that when it encounters the character 'I' that the programmer
literally typed 'I'
rather than \#111 or any
of the other representations the character 'I' has. If a programmer does
use a non-minimally-small escape code for a character inside a
quasistring, syntax-location information will be incorrect for the
remainder of that quasistring.
Contact
If you use this library, please give me feedback! Send comments,
questions, or bug reports to jacobm AT cs.uchicago.edu.