Accumulating history

See textbook: accumulators

Class examples:

;; max : non-empty-list-of-numbers -> num
;;   (Called max-of-list in previous lectures.)
;; Return the largest number in nums.
;; (max-of-list doesn't make sense for empty lists.
;; Possible discussion -- use -inf.0 as sentinel?  Why good or bad?)
;;
(define (max nums)
  (max-helper (rest nums) (first nums)))

;; Given a (possibly empty) list and a number,
;; return the largest
(define (max-helper nums so-far)
   (cond [(empty? nums)  ..]
         [(cons?  nums)  ..(first nums)..(max-helper (rest nums) ..??..)]))




; note the invariant: The largest of so-far and the numbers in nums is always the same.
Step through this.

Recall when we wrote count-female-ancestors, back in lecture 10? It was tough, because we had to count female ancesters, and so you couldn't just recur on ma and pa, because ma's side needed to count the root, and pa's side doesn't. In class we had a solution involving a helper function number-of-mothers: child --> num, that returned either 0 or 1, depending on whether the person had a mother:

;; cfa-version2 : FamTree --> num
;; Count how many female ancestors are in a-ftn.
;;
(define (cfa-version2 a-ftn)
  (cond [(unknown? a-ftn) 0]
	[else (+ (count-mother (child-mother a-ftn))
		 (cfa (child-mother a-ftn))
		 (cfa (child-father a-ftn)))]))

;; count-mother : FamTree --> num
;; Determines how many ancestors to add based on the root of a-ftn
;; -- either 0 or 1.
;;
(define (count-mother a-ftn)
  (cond [(unknown? a-ftn) 0]
	[else             1]))
But there is one more approach (mentioned only in the notes of that lecture):
;; cfa-version3 : FamTree --> num
;; Count how many female ancestors are in a-ftn.
;;
;; How it works [this is NOT part of the purpose]:
;; just call help-cfa, and indicate that the root of the tree
;; is not to be considered a female ancester.
;; (If you have extra knowledge that the person at the root
;; of a-ft is female, and you want to include her in the count,
;; use 1 instead of 0.)
;;
(define (cfa-version3 a-ft)
  (help-cfa a-ft 0))

;; help-cfa: FamTree, num --> num
;; Return how many female ancestors are in a tree,
;; where the root itself is either considered 0 or 1
;; female ancestors; this 0 or 1 is provided
;; as the argument "mothers-at-root".
;;
;; How it works [this paragraph is NOT part of the purpose]:
;; This extra info is provided by the person who called us -- since they
;; might know whether our root is somebody else's mother.)
;; When we make a recursive call, we know whether each subtree
;; has our mother at the root, or our father, and we can
;; call with mothers-at-root set appropriately.
;; 
(define (help-cfa a-ft mothers-at-root)
  (cond [(unknown? a-ft) 0]
        [(child? a-ft) (+ mothers-at-root
                          (help-cfa (child-pa a-ft) 0)
                          (help-cfa (child-ma a-ft) 1))]))

On your own: write !, but use an accumulator. What is your invariant? (I.e., what stays the same, every time the function is called?) This is related to the purpose of your helper.

;; !: natNum --> num
;; Return n!.
;;
(define (! n)
  (!-a n ...))


;; !-a: natNum, num --> num
;; return the product of ...(what?)...
;;
(define (!-a n prod-so-far)
  (cond [(zero? n)     ...]
        [(postive? n)  ..(!-a (sub1 n) ..??..)..]))