Now let us practice writing some simple and useful words.
Example 1: Compounding Interest
Suppose we invest $1000 and we expect that it will grow with
a yearly interest of 6%, which is compounded annually. What will
be the final amount after 10 years?
We can determine the amount of interest accumulated after each year
by taking 6% of the current amount and adding that to the current
amount. For example, you can type the following to compute and print
the amount at the end of the first year:
1000 dup 6 * 100 / + .
We placed the starting amount on the stack, then dup
licated
this value on the stack to compute 6% interest. Finally we add the top two
numbers on the stack, the starting amount and the interest, and print the
sum. If you are confused by the above example, it will help to
print the contents of the stack using .S
after you enter
each word on a separate line, e.g.
1000 .S
dup .S
6 .S
* .S
100 .S
/ .S
+ .S
.
To solve the problem for 10 years, we simply need to repeat this calculation
ten times. Notice that we must skip the first word, 1000
and
the last word, .
, in between years so that we can use the
compounded amount from one year as the starting amount for the next year.
The final result may be printed at the end.
Performing a repetetive calculation is easy in Forth -- it is done with
a DO...LOOP
. The word DO
expects
two numbers on the stack. The difference between the two numbers is the
number of times that the words between DO
and LOOP
will be executed. The smaller number should be on top of the stack
The following word illustrates using the DO...LOOP
to
solve this problem:
: compound10 ( -- | compound 6% interest on $1000 for 10 years and print answer )
1000 \ starting amount
10 0 do \ do this for ten years
dup 6 * 100 / \ compute 6% interest of the current amount
+ \ add interest to the current amount
loop \ loop to next year
. \ finally print the result
;
Executing the word compound10
will display the answer1786
Now let's generalize our word so that it is more useful. We want to be able to specify the starting amount, the interest, and the number of years to compound the interest. Finally, we want to print the result as before. The following word takes inputs from the stack, computes the final amount, and prints the answer:
: compound ( nstart npercent nyears -- )
0 do \ do this for nyears
2dup * 100 / \ compute interest on the current amount
rot + \ add interest to the current amount
swap \ swap items on stack to keep same order for each loop
loop \ loop to next year
drop . \ drop the interest and print the final amount
;
The word compound
assumes that we have entered the starting
amount, the percent interest per year, and the number of years onto the
stack, as indicated in its stack diagram. Therefore, to solve the problem
of our previous example using the more general word we would type1000 6 10 compound
1000 6 20 compound
To conclude this example, let's modify the word compound
so
that it prints a table of the accumulated amount at the end of each year:
: compound ( nstart npercent nyears -- )
0 do
2dup * 100 /
rot +
i 1+ 2 .r \ print the year right justified in 2 character field
9 emit \ print a tab
dup 6 .r \ print year ending amount right justified in 6 char field
cr \ advance to the next line
swap
loop
2drop
;
Notice that we made use of the word I
in the above
example. I
gets the loop index and places it on the
stack. The loop index starts at the number on top of the stack when
DO
executes, which is 0 in this example. The loop index
increments by one after each LOOP
. You can look up in the
dictionary other words that may not be
familiar to you in this example, such as
1+, .R, EMIT,
and CR
.Finally, it is easy in kForth to send the output from the last example to a file instead of printing it on the screen. This is done by typing
>file interest.txt
1000 6 20 compound
console
The word >FILE
redirects output from the screen (console)
to the file name specified subsequently, interest.txt
in
the above example. The word CONSOLE
closes the file and
redirects output back to the screen. We used >FILE
and
CONSOLE
to send the results of our interest calculations to
a file, which can then be imported into a spreadsheet to make a
chart!