Strings with expansion
From Gallium
Contents |
Introduction
This article try to explain the quotation/antiquotation mechanism by comparing them with literal strings, with expansion.
Strings are lexically identified
To start this comparison between quotations and strings, let's talk about the lexical status of strings. Strings are recognized during the lexing phase; this means that almost everything can go into a literal string without a special interpretation.
Example:
let (* is a keyword *) "let" (* is not a keyword *) 42 (* is a literal integer *) "42" (* is not an integer *)
Strings and escaping
Most programming languages feature literal strings with some form of escaping. Commonly the backslash character is taken as the escape character, i.e. to give another meaning than the literal backslash ASCII character.
Example:
"foo" (* a plain string *) "\n" (* this string holds just one character the newline (10nth in ASCII) *) "\\" (* this one holds just one backslash character *)
Strings with expansion
Nowadays many scripting languages have such strings (Sh, Ruby, Perl...). Expansion in strings allow the programmer to embed an expression to be injected in a string.
Example:
- In Shell:
echo "Evaluating $foo gives `calculator $foo`"
- In Ruby:
print "Evaluating #{foo} gives #{calculator(foo)}\n"
So, let's take the Ruby syntax to explain it a little more. In a string, the sequence #{...} is treated specifically. In the case of string, it's simply equivalent to string concatenation.
Example:
"foo#{f(x)}bar" == "foo" + f(x) + "bar"
Given this translation, expansion in strings is very easy. But since this equivalence doesn't hold for general quotations we will no longer use it.
Quotations and antiquotations for strings, and duality
In order to be closer to the goal of explaining quotations, let's give the name of string quotation to "..." and the name of antiquotation to #{...}. One can note that there is a kind of symmetry between quotations and antiquotations. Indeed putting a quotation directly inside an antiquotation is like not having them.
Example:
"foo#{"bar"}moo" == "foobarmoo"
Conversely having in a quotation just an antiquotation is useless too.
Example:
"#{f(x)}" == f(x)
Quotation levels for strings
One can pose that quotations increment the quoting level and antiquotations decrement it.
Example:
"foo\"bar\"baz" (* foo and bar are at level one, and bar at level two *) "a+\"b\#{c+#{d}+e}f\"+g" (* a,g: level 1; b,f: level 2; c,e: level 1; d: level 0 *)
In fact, with strings, reflective levels make sense only if one treat the contents of strings to be in the same language of the host language itself. That case is detailed deeper in the case of Objective Caml, in Reflective OCamls.
To avoid being too complex, let's keep two levels. In the case of strings it can be Ruby for the level 0 and strings contents for the level 1.