Write a tail recursive function called popadd that models a population with P people at time t = 0 and adds d people per year.
(define (popadd t P)
(if (= t 0
Note that neither your code nor the code in the other answer is tail-recursive: in a recursive call like (+ (f ...))
, f
is not in tail position. To make the code tail-recursive you need the result of the recursive call be the result of the overall call (so in the above example, +
is in tail position). To do this you need an auxiliary function. Here is a way of doing it which relies only on local define
:
(define (popadd t P d)
(define (popadd-loop tau pop)
(if (zero? tau)
pop
(popadd-loop (- tau 1) (+ pop d))))
(popadd-loop t P))
Here is essentially the same thing using named-let
, which is nicer:
(define (popadd t P d)
(let popadd-loop ([tau t] [pop P])
(if (zero? tau)
pop
(popadd-loop (- tau 1) (+ pop d)))))
Finally note that this problem has a closed-form solution:
(define (popadd t P d)
(+ P (* t d)))
I really wish that people trying to teach programming knew enough maths to not set problems which have trivial closed-form answers, as doing so encourages people to write inefficient (in the complexity-class sense) code. Obviously this is not your fault: it's your teacher's.
You can simply pass along another parameter to the recursion:
(define (popadd t P d)
(if (= t 0)
P
(+ d (popadd (- t 1) P d))))
Or you can define the value, to avoid passing it around - assuming it doesn't need to change:
(define d 100)
(define (popadd t P)
(if (= t 0)
P
(+ d (popadd (- t 1) P))))
Notice that you could do the same with P
, if it's ok. It really depends on what's the expected contract for the procedure.