SR 2022-2: Symbols as strings

Author

Lassi Kortela

Status

Draft

Abstract

Each Scheme symbol corresponds to a string. This covenience library lets the programmer manipulate the string representations of symbols simply by passing the symbols, omitting the step of converting back and forth between symbols and strings.

Review

This library is patterned after the following prior art.

RnRS provides:

Specification

(symbol-length symbol) -> integer

Returns the string-length of symbol as a string.

(symbol<? symbol1 symbol2) -> boolean

Returns the result of string<? applied to the symbols as strings.

(symbol-ci<? symbol1 symbol2) -> boolean

Returns the result of string-ci<? applied to the symbols as strings.

(symbol-prefix? prefix-string symbol) -> boolean

(symbol-suffix? suffix-string symbol) -> boolean

Returns #t if symbol as a string starts with prefix-string or ends with suffix-string, respectively. Else returns #f.

Matching is case sensitive. A zero-length string matches any symbol.

[Modeled after SRFI 13 string-prefix? and string-suffix?.]

(symbol-middle symbol prefix-string [suffix-string]) -> string

If symbol as a string starts with prefix-string and ends with suffix-string, returns the part between them as a string. Else returns #f.

Matching is done as with symbol-prefix? and symbol-suffix?. If suffix-string is omitted or #f, a zero-length string is assumed.

(symbol-substring symbol start [end]) -> string

Returns the part of symbol as a string between the character indexes start (inclusive) and end (exclusive). If end is omitted of #f, it defaults to the length of the string.

Mutating the result string does not change the symbol.

(symbol-append object ...) -> symbol

Like string-append from RnRS, but the result is a symbol instead of a string, and each object can be any of:

(symbol-transform string-proc symbol arg ...) -> symbol

Return (string->symbol (string-proc (symbol->string symbol) arg ...))

Examples

Comparing symbols

(list-sort symbol<? (features))

Extracting parts of symbols

(symbol-substring 'geronimo 2 6)  ; => "roni"

(symbol-middle 'make-move! "" "")  ; => "make-move!"
(symbol-middle 'make-move! "" "!")  ; => make-move
(symbol-middle 'make-move! "make-" "!")  ; => "move"
(symbol-middle 'make-move! "make+" "!")  ; => #f

Making new symbols

(symbol-append)      ; => ||
(symbol-append #\a)  ; => a
(symbol-append "a")  ; => a

(symbol-append 'foo ":")  => |foo:|

(let ((count 99) (things "bottles") (ask? #f))
  (symbol-append "start-with-" count #\- things
                 (and ask? #\?)))   ; => start-with-99-bottles

(symbol-transform string-upcase 'yeah)  ; => YEAH