# Theory => practice: constructing a function "functionally"

I've read the Mathematica documentation and am certain there's way to do this with functional programming, but can't quite conceive yet how. I've taken a simple example (stating the series for remaining balance on a fixed-interest loan - ignoring the hairsplitting about whether the interest is calculated before or after the first payment is made. I have randomly chosen interest to be applied before payment).

Pj = principal at period j
pmt = payment
i = interest per period

month 0: P1 = P0(1 + i) - pmt
month 1: p2 = (P0(1 + i) - pmt)(1 + i) - pmt
month 2: p3 = ((P0(1 + i) - pmt)(1 + i) - pmt )
month 3: p4 = (((P0 (1 + i) - pmt)(1 + i) - pmt))(1 + i) - pmt


What I want to do is build the state at month N. This is purely practice/learning for building nested functions using Mathematica code. I know the fixed-interest loan-repayment equation is easily derived and easily solved, but my goal here is to learn how to do repeated function application for real-world things -- Nest[f, x, 3] is reminiscent of what I want to do but can't see how to make it work.

Here is what I have tried: pure function:

f = #1 (1 + i) - #2 &


apply it:

f[principal, payment]


response:

(1 + i) P - payment


so, some progress.

I can manually repeatedly apply the pure function thus:

f[(1 + i) P - payment, payment]


to get

(1 + i) ((1 + i) P - payment) - payment


obviously correct, but I can't help thinking that I could get the correct formula by means other than manual application (or a do-while kind of loop).

EDIT: I should point out that as soon as I reduce the pure function to one parameter (P - the remaining principal, which is the only thing that changes), the Next function works.

I am trying to find out how to Nest functions of more than one variable

• Is month 1: similar to month 2? Does this work: f[n_] := Nest[# (i + 1) - payment &, P, n]; f[2] Commented Feb 1, 2015 at 6:46
• Welcome to Mathematica Stack Exchange! In addition to Nest see also NestList, and while you're at it Fold and FoldList as well. If these answer your question I think this can be closed either as a duplicate or easily found in the documentation. If not please indicate how your needs differ. Commented Feb 1, 2015 at 7:20
• I realize this is not the point of your question, but you might want to look at RSolve, which may be able to derive a closed form solution for you. Commented Feb 1, 2015 at 10:00
• thanks to all; until one knows the existence of something that does exactly what is needed (in this case Fold, FoldList) it's quite difficult to ask the question succinctly. In any case, I know an answer to this now, and this can be a springboard for the rest of my function-construction learning Commented Feb 1, 2015 at 22:35

As Algohi pointed out, if payment is the same every month, then you can get a list of payments at each month via (for example)

NestList[# (i + 1) - payment &, P, 2]

(*{P, (1 + i) P - payment, (1 + i) ((1 + i) P - payment) - payment}*)


Otherwise, if payment varies each month, then you can nest functions of two variables using FoldList:

payments = Array[p, 4];
FoldList[# (i + 1) - #2 &, P, payments]

(*{P, (1 + i) P - p[1], (1 + i) ((1 + i) P - p[1]) -
p[2], (1 + i) ((1 + i) ((1 + i) P - p[1]) - p[2]) -
p[3], (1 + i) ((1 + i) ((1 + i) ((1 + i) P - p[1]) - p[2]) - p[3]) -
p[4]}*)

• thanks - I can do this for my (simple learning case):FoldList[# 1 (i + 1) - #2 &, P, Table[p, {4}]] Commented Feb 1, 2015 at 22:32
• @user192127: True, or alternately you could use NestList[# (i + 1) - p &, P, 4]. Commented Feb 1, 2015 at 22:35

Years of Lisp programming makes think the most natural approach to this problem is find a tail-recursive function as a helper function that carries the state of process and does the recursion. The main function will just call the recursive function with the needed initial values.

nxt[val_, pay_, i_, n_] := nxt[val (1 + i) - pay, pay, i, n - 1]
nxt[val_, _, _, 0] := val
r[prin_, i_, pay_, n_] := nxt[prin, pay, i, n]


Then

r[p0, i, pmt, 3]


gives

(1 + i) ((1 + i) ((1 + i) p0 - pmt) - pmt) - pmt


Such tail recursions can be simply transformed in iterations done by Nest.

next[{val_, pay_, i_}] := {val (1 + i) - pay, pay, i}
f[prin_, i_, pay_, n_] := First @ Nest[next, {prin, pay, i}, n]


With these definitions

f[p0, i, pmt, 3]


also gives

(1 + i) ((1 + i) ((1 + i) p0 - pmt) - pmt) - pmt


Note that since Nest` expects to apply a function of one variable, the state of the process is packaged up into a list.

• thanks - agreed there's a multi-line (and maybe this is best, all things considered) way to do it. Thanks, appreciated. I'd vote up if I had 15 reputation). FoldList seems another way to achieve this in one step Commented Feb 1, 2015 at 22:30