From e5a2e91c4243745aeedba4408c067a734d327d19 Mon Sep 17 00:00:00 2001 From: Lassi Kortela Date: Thu, 1 Dec 2022 20:40:16 +0200 Subject: [PATCH] Initial commit --- code/symbols-as-strings.sld | 86 +++++++++++++++++++++++++ document.md | 123 ++++++++++++++++++++++++++++++++++++ 2 files changed, 209 insertions(+) create mode 100644 code/symbols-as-strings.sld create mode 100644 document.md diff --git a/code/symbols-as-strings.sld b/code/symbols-as-strings.sld new file mode 100644 index 0000000..1668507 --- /dev/null +++ b/code/symbols-as-strings.sld @@ -0,0 +1,86 @@ +(define-library (symbols-as-strings) + (export symbol-length + symbolstring symbol))) + + (define (symbolstring symbol1) + (symbol->string symbol2))) + + (define (symbol-cistring 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))))) diff --git a/document.md b/document.md new file mode 100644 index 0000000..1d3fbee --- /dev/null +++ b/document.md @@ -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 boolean` + +Returns the result of *string boolean` + +Returns the result of *string-ci 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 "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 +```