String literals

Simple literals

String literals are bounded by double quotes (").
They support the same escape sequences as JSON.

main void() log "a\n\t\u20bf"

"quote" strings

The quote keyword introduces an indented multi-line string.
These support escape sequences and interpolation too.

main void() log quote Bereft of quote marks, Using an indented block I wrote a haiku

Interpolation

String interpolation works with any type that defines a show function.
Interpolated values go in braces ({}).

main void() log "{foo 1, 2}" log show foo 1, 2 # equivalent foo record(x nat, y nat) show string(a foo) "<{a.x}, {a.y}>"

Interpolating other types

Other string-like types support interpolation too.

main void() s symbol = "1 + 1 is {1 + 1}" log show s j json = "2 * 2 is {2 * 2}" log show j

Interpolating custom types

For json and symbol, interpolation just creates a string and converts it to the appropriate type.
But custom interpolation can also be used to have different behavior for interpolated values.

Defining custom interpolation involves 3 parts:

  • An interpolate-string function that prepares a literal part. (This means a part not inside {}.)
    This can return any type.
  • An interpolate-value function that prepares an interpolated part. (This means a part inside {}.)
    This must return the same type as interpolate-string.
  • An interpolate function that combines all parts into a result.
import keen/string/util main void() id string = "1; drop table precious_data;" a sql = "select * where id = {id}" log a.query sql record(query string) sql-part record(value string) interpolate sql(parts sql-part[]) query: join map parts, it.value interpolate-string sql-part(a string) value: a interpolate-value sql-part(a string) value: quoted a

"a{b}c" is equivalent to:
interpolate ( "a".interpolate-string, b.interpolate-value, "c".interpolate-string)

For strings, interpolate-string is the identity function, while interpolate-value calls show.

Notice how id got quoted by interpolate-value.