1. Verify that the input is either a word or a sentence and then make sure it is not empty. (bf "") and (bf '()) would both return errors.

(define safe-bf 
  (type-check
   bf
   (lambda (x) 
     (and (or (word? x) (sentence? x))
          (not (empty? x))))))

2. Since vowel? is not part of Scheme, it should ideally be written as well.

The trick here is that the vowels in the sentence need to be made into a word. (Solution provided by Sabrina Lui.)

(define (vowel? ltr)
  (member? ltr 'aeiou))

(define (num-vowels sent)
  (let ((wd (accumulate word sent)))
    (count (keep vowel? wd))))

3. abracadabra

The reason for this is that accumulate works right to left on the input sentence. The behavior essentially works like this:

  • The rightmost two elements are read into c1 and c2;
  • The result of the word function replaces those terms in the original sentence;
  • The above two steps are repeated until there is one word left;
  • The one word is what is returned by accumulate.
    (accumulate (lambda (c1 c2) (word 'a c1 c2)) '(br c d br "" ""))
    (accumulate (lambda (c1 c2) (word 'a c1 c2)) '(br c d br a)) 
    (accumulate (lambda (c1 c2) (word 'a c1 c2)) '(br c d abra)) 
    (accumulate (lambda (c1 c2) (word 'a c1 c2)) '(br c adabra)) 
    (accumulate (lambda (c1 c2) (word 'a c1 c2)) '(br acadabra)) 
    (accumulate (lambda (c1 c2) (word 'a c1 c2)) '(abracadabra)) 
    abracadabra