Initial commit

This commit is contained in:
Lassi Kortela 2022-12-01 20:40:16 +02:00
commit e5a2e91c42
2 changed files with 209 additions and 0 deletions

View File

@ -0,0 +1,86 @@
(define-library (symbols-as-strings)
(export symbol-length
symbol<?
symbol-ci<?
symbol-prefix?
symbol-suffix?
symbol-middle
symbol-substring
symbol-append
symbol-transform)
(import (scheme base)
(scheme case-lambda))
(cond-expand ((library (srfi 13))
(import (only (srfi 13)
string-prefix?
string-suffix?)))
((library (srfi 130))
(import (only (srfi 130)
string-prefix?
string-suffix?))))
(begin
(define (symbol-length symbol)
(string-length (symbol->string symbol)))
(define (symbol<? symbol1 symbol2)
(string<? (symbol->string symbol1)
(symbol->string symbol2)))
(define (symbol-ci<? symbol1 symbol2)
(string-ci<? (symbol->string symbol1)
(symbol->string symbol2)))
(define (symbol-prefix? prefix symbol)
(string-prefix? prefix symbol))
(define (symbol-suffix? suffix symbol)
(string-suffix? suffix symbol))
(define symbol-middle
(case-lambda
((symbol prefix)
(symbol-middle symbol prefix ""))
((symbol prefix suffix)
(let ((suffix (or suffix ""))
(str (symbol->string symbol)))
(and (string-prefix? prefix str)
(string-suffix? suffix str)
(substring str
(string-length prefix)
(- (string-length str)
(string-length suffix))))))))
(define symbol-substring
(case-lambda
((symbol start)
(let ((str (symbol->string symbol)))
(substring str start (string-length str))))
((symbol start end)
(let ((str (symbol->string symbol)))
(substring str start (or end (string-length str)))))))
(define (symbol-append . parts)
(string->symbol
(apply string-append
(map (lambda (part)
(cond ((string? part)
part)
((char? part)
(string part))
((symbol? part)
(symbol->string part))
((and (integer? part)
(exact? part)
(not (negative? part)))
(number->string part))
((not part)
"")
(else
(error "Bad symbol part" part))))
parts))))
(define (symbol-transform string-proc symbol . args)
(string->symbol (apply string-proc
(symbol->string symbol)
args)))))

123
document.md Normal file
View File

@ -0,0 +1,123 @@
# 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.
* 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
```