Scheme Quasistring

Unleash your inner Perl programmer!

by Jacob Matthews - download - source

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:

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

DrScheme error highlighting works with quasistring
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:
  1. In DrScheme, select File -> Install .plt File ... and select the "Web" tab.
  2. 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.