Checked literals
A string literal where a Path, a Uri, a UriTemplate, a Regex or a resource type is expected is read by the compiler where it is written, and one that is not valid is a compile error at that line; a template and a pattern are read verbatim.
Diese Seite gibt es noch nicht auf Deutsch, deshalb steht sie hier auf Englisch. Zur englischen Seite
A string literal whose expected type is one of a closed list of types of the standard library is a value of that type,
read by the compiler where it is written. A literal that is not a valid value of the type is a compile error at that
line, and a String value never becomes one: text that is only known when the program runs goes through the type's own
tryFrom, which says what was wrong with it.
Example#
use Regex from "std/regex"
use UriTemplate from "std/uri"
fn host(of: Uri): String {
of.host()?.show() ?? "none"
}
type OrderPath {
id: Int
}
print host("https://Example.TEST/orders")
const year: Regex = "(?P<year>\d{4})-\d{2}"
print year.find("due 2026-10")?.named("year")
const orders: UriTemplate<OrderPath> = "/orders/{id}"
print orders.expandedFrom(OrderPath(7))
const config: Path = "config/app.trb"
print config.name()\d{4} needs no raw: where a Regex or a UriTemplate is expected, the literal is the pattern or the template as
it stands, and {id} is the template's variable, not an interpolation.
Syntax#
fn open(target: Uri) { ... }
open "https://example.test/a" a literal where a Uri is expected
const pattern: Regex = "\w+@\w+" read verbatim: no escape sequences, no interpolation
const route: UriTemplate<Order> = "/o/{id}" read verbatim, and checked against the fields of Order
Uri.tryFrom(text)? a String value, read while the program runsRules#
The list is closed.
Path(std/path),UriandUriReference(std/uri),UriTemplate(std/uri),Regex(std/regex), andResource,EmbeddedBytesandEmbeddedText(std/resource). A type of your own withTryFrom<String, _>is not on it: the compiler would have to run the program it is compiling to check the literal.Only a literal is read, and only where the type itself is expected. A parameter, an annotated binding, a field, a return value and the items of a list literal expect a type.
const text = "https://…"followed byopen(text)is aStringhanded to aUri, and so is a literal where aUri?is expected - exactly as1does not adapt to aFloat?.A literal that is not a valid value is an error at the literal. The compiler runs the type's own parser on it:
Uri.tryFrom,UriTemplate.tryFrom,Regex.tryFrom. A message about a pattern points at the character it fails at; a relative reference where aUriis expected gets a message of its own.Kompiliert nichtuse Regex from "std/regex" const broken: Regex = "ab(cd" // error: `ab(cd` is not a regular expression: a `(` is not closedA
Regexand aUriTemplateliteral are read verbatim. Their backslashes and braces are the pattern's and the template's grammar, so the literal has no escape sequences and no interpolation, andraw"..."is not needed. The same text where aStringis expected keeps its escapes, and there\dis an error.Every other checked literal cannot be interpolated. A
Uri, aPathor a resource literal is read where it is written, and a hole in it would be filled only when the program runs.Kompiliert nichtconst name = "guide" const page: Uri = "https://example.test/{name}" // error: A `Uri` literal is parsed where it is written, so it cannot be interpolatedA
Stringvalue is not converted. The message names the function that reads one while the program runs.Kompiliert nichtfn open(target: Uri) {} const address = "https://example.test/" open address // error: Expected `Uri`, found `String`A template typed against a record is checked against its fields. Every variable is a field, every field without a default is a variable, and a field with a default is at most a query variable (
{?page}), which a request may leave out.route(template, to: Route.Order)checks the template against the case it names the same way.Kompiliert nichtuse UriTemplate from "std/uri" type OrderPath { id: Int } const orders: UriTemplate<OrderPath> = "/orders/{identifier}" // error: `identifier` of `/orders/{identifier}` is not a field of `OrderPath` // error: `OrderPath.id` has no default, and `/orders/{identifier}` has no variable for itA resource literal names a file of the package, relative to the file that writes it. A file that is not there, one outside the package, and one whose name differs only in case are errors at the literal, on every platform.
The value is built once per program. The compiler records what it read, and the first evaluation builds the value that every later one - a
Regexliteral inside a loop included - reads again.
What this is not#
Not a conversion. Nothing turns a String into a Uri implicitly, and there is no Into<Uri> parameter: the
literal is the one case the compiler can check, and every other text goes through a Result.
Not a new kind of literal. There is no /.../ for a pattern and no u"..." for a URI: the expected type decides,
the way it decides that 1 is a Float where a Float is expected.
Related#
- Literal types - the other place a string literal adapts to the expected type.
- Strings - escape sequences and interpolation, which a verbatim literal does not have.
- std/uri -
Uri,UriTemplateand routes. - std/regex - the patterns a
Regexliteral is compiled with.