124 lines
3.1 KiB

# SR 2022-2: Symbols as strings
## Author
Lassi Kortela
## Status
## 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.
* R7RS
* SRFI 13 (String Libraries)
* SRFI 115 (Scheme Regular Expressions)
RnRS provides:
* `symbol?`
* `symbol=?`
* `symbol->string`
* `string->symbol`
## 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:
* a string
* a character (converted as if by *string*)
* a symbol (converted as if by *symbol->string*)
* a non-negative exact integer (converted as if by *number->string*)
* `#f` (ignored as if it were a zero-length string)
`(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