Generalized literals for Kawa

Tue, 28 Aug 2012 17:32:19 -0700
Scheme, draft, kawa

This note is a rationale and design discussion of a number Kawa feature for more powerful string and other literals. This feature aims to satisfy a number of related needs.

Using Kawa string literals for long multi-line strings is awkward. One problem is that the same delimiter (double-quote) is used for both the start and end of the string. This is error-prone and not robust: adding or removing a single character changes the reading of the entire rest of the program. A related problem is that the delimiter needs to be quoted using an escape character, which can get hard-to-read.
A common solution is a here document, where distinct multi-character start and end delimiters are used. For example the Unix shell uses uses << followed by an arbitrary token as the start delimiter, and then the same token as the end delimiter:

tr a-z A-Z <<END_TEXT
one two three
uno dos tres
END_TEXT

This proposal would use:

(string-upcase #&[
one two three
uno dos tres
])

Commonly one wants to construct a string as a concatenation of literal text with evaluated expressions. Using explicit string concatenation (Scheme string-append or Java's + operator) is verbose and can be error-prone. Using format is an alternative, but it is also a bit verbose, and has the problem that the format specifier in the string is widely separated from the expression. Nicer is to be able to use Variable interpolation, as in Unix shells:

echo "Hello ${name}!"

This proposal uses the syntax:

#&[Hello &{name}!]

Note that & is used for two different related purposes: Part of the prefix #&[ to mark the entire string, and as an escape character for the variable interpolation. This will be justified shortly.
Going one step further, template processor has many uses. Examples include BRL and JSP, which are both used to generate web pages.
The simple solution is to allow general Kawa expressions in substitutions:

#&[Hello &{(string-capitalize name)}!]

You can also leave out the curly braces when the expression is a parenthesized expression:

#&[Hello &(string-capitalize name)!]

Note that this syntax for unquoted expressions matches that used in Kawa's XML literals.
The Scribble system defines a language for writing documents. It is a kind of template processor with embedded expression in the Racket Scheme dialect. The general Racket syntax for an embedded expression is:

@cmd[datum ...]{text-body}

Kawa switches the roles of {} and [] to be compatible with XML-literals, and also because {} is more commonly used for anti-quotation. Kawa uses special characters, so it becomes:

&cmd{datum ...}[text-body]

This form translates to:

(cmd datum ... #&[text-body])

Camp4 quotation SRFI-10 Example: #&sql[select * from person where firstname != ${ignore}]