Mutual recursion in racket, making cond do two things

2.1k views Asked by At

I have two definitions, for a family tree and a person.

; a family-tree is:
;   (make-person list-of-family-tree symbol number symbol)
; a person is:
;   (define-struct person [children name date eyes])

I need to make a "mutually recursive" function that counts the number of descendants in a tree (including the person). But I can't figure out how to make cond do more than one thing if a condition is met.

i.e.:

(define (count-descendants person1)
  (cond [(empty? (person-children person1)) +0]
        [else (count-descendants (first (person-children person1)))/*also +1 here*/
              (count-descendants (rest (person-children person1)))/*also +1 here*/]))

Any idea how to recursively call the function on the other parts of the list, AND add one?

1

There are 1 answers

1
Rptx On BEST ANSWER

What you ask is accomplished with a begin expression. But you don't need that here. You need to combine the result of the 2 recursive calls. In your case, you need to add 1 (the current person) to the result of calling count-descendants on every child. Another error in your function is that you use first and rest for the person-children but your function is not designed to handle a list of persons. when you call it on empty, you will get an error because you can't get person-children of empty. Finally, in the case a person doesn't have children, I believe it should still be counted, so I return 1 in that case. So adding all this up, you must end up with something like this:

(define (count-descendants person1)
  (cond [(empty? (person-children person1)) 1]
        [else (+ 1 
              (foldl + 0 (map count-descendants (person-children person1))))]))

In here, I use map to count the descendants of all the children of person1, and foldl to add up the result.