; higher-order string functions
(define (string-map proc str)
(let* ((len (string-length str))
(out (make-string len)))
(do ((i 0 (+ i 1)))
((= i len) out)
(string-set! out i
(proc (string-ref str i))))))
(define (shift c n)
(cond ((char-upper-case? c)
(integer->char (+ (modulo (+ (char->integer c) -65 n) 26) 65)))
((char-lower-case? c)
(integer->char (+ (modulo (+ (char->integer c) -97 n) 26) 97)))
(else c)))
(define (caesar n str)
(string-map (lambda (c) (shift c n)) str))
(display (caesar 3 "PROGRAMMING praxis")) (newline)
(display (caesar -3 "SURJUDPPLQJ sudalv")) (newline)
(define (string-for-each proc str)
(do ((i 0 (+ i 1)))
((= i (string-length str)))
(proc (string-ref str i))))
(string-for-each
(lambda (c) (display (char->integer c)) (newline))
"PRAXIS")
(define (string-fold proc base str)
(let loop ((base base) (i 0))
(if (= i (string-length str)) base
(loop (proc (string-ref str i) base) (+ i 1)))))
(define (string-fold-right proc base str)
(let loop ((base base) (i (- (string-length str) 1)))
(if (negative? i) base
(loop (proc (string-ref str i) base) (- i 1)))))
(display (string-fold cons '() "PRAXIS")) (newline)
(display (string-fold (lambda (c count)
(if (char-lower-case? c)
(+ count 1)
count))
0 "Programming Praxis"))
(newline)
(string-fold (lambda (c junk)
(display (char->integer c)) (newline))
0 "PRAXIS")
(display (list->string ; double characters
(string-fold-right (lambda (c base)
(cons c (cons c base)))
'() "PRAXIS")))
(newline)