mirror of
https://github.com/ruuda/rcl.git
synced 2025-12-23 04:47:19 +00:00
115 lines
3 KiB
Markdown
115 lines
3 KiB
Markdown
# Strings
|
|
|
|
RCL has multiple forms of string literals. String literals in <abbr>RCL</abbr>
|
|
support string interpolation and are most similar to those in Python, with some
|
|
inspiration from Nix and Rust. All json strings are valid in <abbr>RCL</abbr>[^1].
|
|
|
|
Strings can be quoted with double quotes:
|
|
|
|
```rcl
|
|
"Hello, world"
|
|
```
|
|
|
|
Or with triple double quotes:
|
|
|
|
```rcl
|
|
"""
|
|
Hello, world
|
|
"""
|
|
```
|
|
|
|
In both cases, add an `f` to enable interpolation.
|
|
|
|
```rcl
|
|
f"Hello {greetee}"
|
|
```
|
|
|
|
[^1]: Except for `\u` escape sequences that encode surrogate code points
|
|
(U+D800 through U+DFFF). While a pair of such escape sequences may together
|
|
be valid, a single one is not, so at this point <abbr>RCL</abbr> opts to not
|
|
implement surrogate
|
|
pairs.
|
|
|
|
## Multiline strings
|
|
|
|
In all string literals, newlines are preserved verbatim. Inside a `"""`-quoted
|
|
string, any shared leading whitespace gets removed, as well as the mandatory
|
|
newline that directly follows the `"""`. If there is a trailing newline, then
|
|
that one _is_ part of the string. The following strings are identical:
|
|
|
|
```rcl
|
|
let a = "Hello\n World\n";
|
|
let b = "Hello
|
|
World\n";
|
|
let c =
|
|
"""
|
|
Hello
|
|
World
|
|
""";
|
|
let d =
|
|
"""
|
|
Hello
|
|
World\n""";
|
|
```
|
|
|
|
Inside a `"`-quoted string, `"` itself needs to be escaped as `\"`, but inside
|
|
a `"""`-quoted string, `"` does not need to be escaped. Inside a `"""`-quoted
|
|
string, `"""` itself needs to be escaped, but escaping one of the three quotes
|
|
is sufficient.
|
|
|
|
Blank lines inside the string do not defeat shared leading whitespace. This
|
|
means that the following expression returns true without any of the lines in
|
|
the document containing trailing whitespace:
|
|
|
|
```rcl
|
|
let x =
|
|
"""
|
|
Section 1
|
|
|
|
Section 2
|
|
""";
|
|
let y = "Section 1\n\nSection 2\n";
|
|
x == y
|
|
```
|
|
|
|
## Interpolation
|
|
|
|
When an `f` precedes a string literal, this enables _interpolation_, and the
|
|
string is called a _format string_ or _f-string_ for short. Interpolation means
|
|
that the string literal should have one or more _holes_, delimited by `{}`. The
|
|
hole can contain any expression that evaluates to a string. (TODO: How to type
|
|
string formattable types?). Holes can themselves contain format strings, there
|
|
is no nesting limitation. (Like in Nix, but unlike Python.)
|
|
|
|
An example of string interpolation:
|
|
|
|
```rcl
|
|
let generations = {
|
|
"Leon Kowalski": 6,
|
|
"Rachael": 7,
|
|
"Roy Batty": 6,
|
|
};
|
|
[
|
|
for name, generation in generations:
|
|
f"{name} was a Nexus-{generation} replicant."
|
|
]
|
|
```
|
|
|
|
## Escape sequences
|
|
|
|
Inside strings, `\` initiates an escape sequence. The same escape sequences as
|
|
in json are supported, which includes `\"`, `\\`, `\r`, `\n`, and `\t`.
|
|
Furthermore, `\{` escapes `{` inside format strings. `}` does not need to be
|
|
escaped, but for symmetry `\}` is allowed as an escape for `}`.
|
|
|
|
A `\u` initiates an escape sequence for an arbitrary Unicode scalar value. It
|
|
can be followed by either exactly 4 hex digits (like in json and Python), or by
|
|
a variable number of hex digits enclosed in `{}` (like in Rust). The following
|
|
strings are identical:
|
|
|
|
```rcl
|
|
let a = "\n";
|
|
let b = "\u000a";
|
|
let c = "\u{0a}";
|
|
let d = "\u{00000a}";
|
|
```
|