; changing gender
(define (all? pred? xs)
(cond ((null? xs) #t)
((pred? (car xs))
(all? pred? (cdr xs)))
(else #f)))
(define gender-words '(
("boy" "girl") ("girl" "boy")
("boyfriend" "girlfriend") ("girlfriend" "boyfriend")
("father" "mother") ("mother" "father")
("husband" "wife") ("wife" "husband")
("brother" "sister") ("sister" "brother")
("he" "she") ("she" "he")
("his" "her") ("her" "his")
("male" "female") ("female" "male")
("man" "woman") ("woman" "man")
("mr" "ms") ("mr" "ms")
("sir" "madam") ("madam" "sir")
("son" "daughter") ("daughter" "son")
("uncle" "aunt") ("aunt" "uncle")))
(define (split str)
(let loop ((cs (string->list str)) (word (list)) (words (list)))
(cond ((null? cs)
(reverse (if (null? word) words
(cons (list->string (reverse word)) words))))
((char-alphabetic? (car cs))
(loop (cdr cs) (cons (car cs) word) words))
((pair? word)
(loop (cdr cs) (list) (cons (string (car cs))
(cons (list->string (reverse word)) words))))
(else (loop (cdr cs) word (cons (string (car cs)) words))))))
(define (replace word)
(let* ((d (string-downcase word))
(w (assoc d gender-words))
(w (if w (cadr w) d))
(w (string->list w)))
(cond ((all? char-upper-case? (string->list word))
(apply string (map char-upcase w)))
((char-upper-case? (car (string->list word)))
(list->string (cons (char-upcase (car w)) (cdr w))))
(else (list->string w)))))
(define (change-gender str)
(apply string-append (map replace (split str))))
(display (change-gender "My Brother's girlfriend is taking HER sister to the movies."))