This page is part of the web mail archives of SRFI 13 from before July 7th, 2015. The new archives for SRFI 13 contain all messages, not just those from before July 7th, 2015.
Hello everyone. A few comments and suggestions on SRFI-13. string-take string-drop string-take-right string-drop-right substring-move-left substring-move-right These (if needed) can all be defined as special cases of a more general function, string-replace. string-replace s1 start end s2 -> string replace the substring of s1 from start to end with s2 A variant, string-replace! could also be defined, which is allowed to reuse the original storage of s1. With a regexp package, regexp matching could used to find start and end points, then string-replace could perform the replacement. My sample code defines two equivalent versions of string-replace. String-replace-simple does string replacement using substrings and append; string-replace allocates a new string and copies characters into it. ------------ reverse-string-concatenate string-list [end] -> string reverse-string-concatenate/shared string-list [end] -> string Why are these included? Without the optional parameter, the stated equivalents are clearer. With END these functions are odd -- why are they needed? ------------ string-filter s char/char-set/pred [start end] -> string string-delete s char/char-set/pred [start end] -> string The char/char-set/pred isn't intuitive. If char-sets are needed, perhaps there should be a set package SRFI (is there one already?), or the functionality could be provided by a regexp package. Suggest dropping string-delete and using an alternative version of string-filter which uses a string -> string function f instead of char/char-set/pred. (String deletion can be done by f returning "".) The function f should go first, as with map and string-map. string-filter f s [start end] -> string construct a string by applying f to each character of s function f should take a string of length one as input, and output a string (of any length) ------------ Example code (written in MzScheme) is below. Enjoy. ;;; dw-string.scm -- a few string manipulation functions ;;; these functions are for illustration, and lack error checking ; filter a string s using function f (define (string-filter f s . endpoints) (let ((start 0) (end (string-length s))) (if (not (null? endpoints)) (begin (set! start (car endpoints)) (set! end (cadr endpoints)))) (string-append (substring s 0 start) (apply string-append (map f (map string (string->list (substring s start end))))) (substring s end (string-length s))))) ; map a character-transforming function over a string ; does not take substring endpoints (define (string-map f s) (list->string (map f (string->list s)))) ; destructive version of string-map ; modifies the original string ; does not take substring endpoints (define (string-map! f s) (do ((i (- (string-length s) 1) (- i 1))) ((< i 0) 'ok) (string-set! s i (f (string-ref s i))))) ; replace substring of s1 with s2 (define (string-replace-simple s1 start end s2) (string-append (substring s1 0 start) s2 (substring s1 end (string-length s1)))) ; string-copy!, needed for efficient version of replacement ; substring endpoints should be optional (define (string-copy! target tstart s start end) (do ((i tstart (+ i 1)) (j start (+ j 1))) ((= j end) 'ok) (string-set! target i (string-ref s j)))) ; replacement, efficient version ; equivalent to string-replace-simple (define (string-replace s1 start end s2) (let ((result (make-string (+ (string-length s1) (- start end) ; this should be nonpositive (string-length s2))))) ; copy first part of s1 into result (string-copy! result 0 s1 0 start) ; copy s2 into result (string-copy! result start s2 0 (string-length s2)) ; copy second part of s1 into result (string-copy! result (+ start (string-length s2)) s1 end (string-length s1)) ; return result result)) ;; the first two functions below demonstrate uses of string-filter ;; which could not be done by string-map ; test string-filter: remove the vowels from a string (define (remove-vowels s) (string-filter (lambda (s1) (if (member (string-ref s1 0) (string->list "AEIOUaeiou")) "" (substring s1 0 1))) s)) ; another example of string-filter (define (local-echo s) (string-filter (lambda (s1) (string-append s1 s1)) s)) ;; example of using string-map ; rot13 of a character (define (rot13 c) (cond ((char-upper-case? c) (integer->char (if (char<? c #\N) (+ (char->integer c) 13) (- (char->integer c) 13)))) ((char-lower-case? c) (integer->char (if (char<? c #\n) (+ (char->integer c) 13) (- (char->integer c) 13)))) (else c))) ; rot13 of a string (define (string-rot13 s) (string-map rot13 s))