; spelling numbers
(define range
(case-lambda
((stop) (range 0 stop (if (negative? stop) -1 1)))
((start stop) (range start stop (if (< start stop) 1 -1)))
((start stop step)
(let ((le? (if (negative? step) >= <=)))
(let loop ((x start) (xs (list)))
(if (le? stop x) (reverse xs)
(loop (+ x step) (cons x xs))))))
(else (error 'range "too many arguments"))))
(define (spell n)
(let ((ones '("" "one" "two" "three" "four" "five" "six"
"seven" "eight" "nine" "ten" "eleven"
"twelve" "thirteen" "fourteen" "fifteen"
"sixteen" "seventeen" "eighteen" "nineteen"))
(tens '("" "" "twenty" "thirty" "forty" "fifty"
"sixty" "seventy" "eighty" "ninety")))
(cond ((negative? n) (error 'spell "too small"))
((zero? n) "zero")
((< n 20) (list-ref ones n))
((< n 100) (string-append
(list-ref tens (quotient n 10))
(list-ref ones (modulo n 10))))
((= n 100) "onehundred")
(else (error 'spell "too big")))))
(display (sort (range 101) (lambda (a b) (string<? (spell a) (spell b))))) (newline)