User:Brian Schott/Essay/J-in-5

From J Wiki
Jump to navigation Jump to search

Using Insert, Suffix, and Forks as a J-in-5-Minutes subject

Don't make the mistake of thinking this essay is about finance. It's about the beauty, eccentricities, and power of J

With a financial example of computing the ending balance after three years on a $10,000 loan at 5% interest, I want to show key features and idiosyncrasies of J relative to some other computer languages, especially J's aversion to coding with loops and its use of verb Forks. Computing the ending balance is a simple enough problem and there is a standard, closed-form mathematical formula. This formula is in two parts: the first is Future Value (after 3 years of $10,000) and is explained here [1] ; the second part is subtracted and is called the Future Value of an ordinary annuity (of $1000 annually) here [2] .

   (10000*1.05^3)-1000*(1-~1.05^3)%0.05
8423.75

But, the beauty of J can be see by approaching the problem from an incremental perspective. First, define a list of payment amounts. We place the first payment at the end of the list to accommodate J's parsing from right to left.

   p=. 3 #  1000  NB. first payment is in last position.
   p,10000

The / in the formula is a J adverb named Insert. Insert places the verb to its left between each pair of data values. The verb in this case is update spelled upd.

   NB. upd/p,10000

In upd in parentheses, the balance, bal, is multiplied by the growth factor 1.05, first. That term is itself a Fork consisting of three tines with the time sign the middle tine. Once computed, the parenthesized term becomes the left most tine in the all-inclusive expression, a Fork of three tines. Notice also, bal is defined as a Fork which takes the rightmost data item from the date pair. Similarly the payment verb is a Fork. In upd the expression in parentheses is called Future Value and is explained here [3] .

   upd=. (1.05*bal)-pmt
   pmt=. [ NB. 'left argument', always 1000 in our example
   bal=. ] NB. 'right argument', 10000 at first,
           NB. then after a payment is subracted, the new balance

And we get the desired result by entering the formula into J.

   upd/p,10000
8423.75

To better see the intermediate symbolic calculations a knew verb z is defined. The details of z are not important to our purpose here. Notice that z is inserted between the data pairs, just as upd is inserted above.

   z=. ('(','1.05*',bal,')-',pmt)/@,:&":

After the main calculations, deb removes space characters from the symbolic phrase.

Looking at the middle of the symbolic phrase, we see that first the $10,000 balance is multiplied by the growth factor 1.05 and then the $1000 first payment is subtracted. Moving outward in the expression, that balance of $9500 is multiplied by a growth factor and then another $1000 is subtracted. And this process is repeated one more time.

   deb z / p , 10000
(1.05*(1.05*(1.05*10000)-1000 )-1000 )-1000

Even this symbolic expression can be entered as a line of code into J, and executed, to get the same result as above.

   (1.05*(1.05*(1.05*10000)-1000 )-1000 )-1000
8423.75

To further demonstrate the implicit looping powers of J, we look into making the same calculation as above, but for every duration in the list, not just the full duration. To do so, we use the adverb named Suffix, (\.), which reconstructs the data to apply its verb to each suffix of the data, starting with the whole data set.

   <\. p , 10000
┌────────────────────┬───────────────┬──────────┬─────┐
│1000 1000 1000 10000│1000 1000 10000│1000 10000│10000│
└────────────────────┴───────────────┴──────────┴─────┘

If, instead of boxing each suffix, we insert our upd verb, the desired result is computed for each duration. While it might be expected that this repeated calculation would be very inefficient, the developers of J have included special code in the interpreter, which eliminates the duplication.

   upd/\. p , 10000
8423.75 8975 9500 10000

By profiling the upd process using the timespacex verb, we see that the Suffix operation is quite efficient. The space requirement barely doubles, and the time increases only slightly, in the ratio 2.5 to 2.7.

   p=. 10# 1000
   timespacex 'upd / p, 10000'
2.5e_5 3712
   timespacex 'upd /\. p, 10000'
2.7e_5 7552

You'll want to look at [4] for an essay on Insert because it shows a wide variety of uses of this fundamental operator in J.

I have included a couple of more examples to demonstrate how a plot of the results and labeling of the results can easily be accomplished.

   (,:~|.@i.@#)upd/\.p,10000
     10       9       8    7       6       5       4       3    2    1     0
3711.05 4486.72 5225.45 5929 6599.04 7237.18 7844.94 8423.75 8975 9500 10000
   load'plot'
   plot;/(,:~|.@i.@#)upd/\.p,10000

balances

The next example shows how to compare 5% and 8% interest rates by defining an adverb, aupd. Another variation would involve changing the payments to change over time by entering a new payment list.

   aupd =. adverb : '(m*bal)-pmt'
   1.05 aupd/p,10000
3711.05
   1.05 aupd/\.p,10000
3711.05 4486.72 5225.45 5929 6599.04 7237.18 7844.94 8423.75 8975 9500 10000
   plot |."1(,:~|.@i.@({:@$))(1.08 aupd/\.p,10000),:upd/\.p,10000

Coding in the programming language J can eschew loops and employ a syntactical feature called a Fork, which often supplies an algebraic symbolism to expressions. J can be downloaded for a variety of platforms, (even including some mobile), and a new front end of the interpreter even utilizes standard browsers for use and for development.