Elegant Programming

&. dfh

Chris Burke
cburke@jsoftware.com

J defines inverses for many functions, and provides various ways of making use of them. The elegant title expression provides an interesting example.

First define:

   dfh=. 16&#. @ ('0123456789ABCDEF'&i.)    NB. decimal from hex

   hex=. &. dfh

Then:

   'FEED' + hex 'B'
FEF8	

   'FF' * hex '101'
FFFF

Thus, hex is an adverb which returns a verb that works in hexadecimal.

Under

The definition of hex uses the conjunction &. (under). Given verbs u and v where the inverse v-1 is defined, then u&.v is equivalent to v-1 u v.

Here are some examples, using &.:

inverse of natural log is the exponential:

   3 + &. ^. 4
12

inverse of reciprocal is itself:

   am=. +/ % #       NB. arithmetic mean
   hm=. am &. %      NB. harmonic mean
   hm 2 3 5
2.90323

inverse of open is box:

   n=. 'winston';(i.3 4);10 20
   # &.> n
+-+-+-+
|7|3|2|
+-+-+-+

   $ &.> n
+-+---+-+
|7|3 4|2|
+-+---+-+
   
   each=. &.>
   |. each n
+-------+---------+-----+
|notsniw|8 9 10 11|20 10|
|       |4 5  6  7|     |
|       |0 1  2  3|     |
+-------+---------+-----+

inverse of the binary representation is the base-2 value:

   bitwise=. &.#:

   5 +. bitwise 6     NB. bitwise OR
7

   5 *. bitwise 6     NB. bitwise AND
4

   5 ~: bitwise 6     NB. bitwise XOR
3

inverse of transpose is itself:

   +/\ i.3 4          NB. accumulate along columns
 0  1  2  3
 4  6  8 10
12 15 18 21

   +/\ &.|:  i.3 4    NB. accumulate along rows
0  1  3  6
4  9 15 22
8 17 27 38

Inverse

You can access the inverse directly using ^:_1 (power of minus 1). For example, define:
   inv=. ^:_1

inverse of add 2 is subtract 2:

   +&2 inv 1 2 3
_1 0 1

inverse of sum scan is first differences:

   +/\ inv 2 3 5 7 11
2 1 2 2 4

inverse of product scan is rate of increase:

   */\ inv 2 3 5 7 11
2 1.5 1.66667 1.4 1.57143

   ({.,}.%}:) 2 3 5 7 11
2 1.5 1.66667 1.4 1.57143

inverse of p: determines number of smaller primes:

   p: 100000         NB. 100000'th prime
1299721
      
   p: inv 1299721    NB. number of primes less than 1299721
100000

Obverse

You can define inverses for use with the conjunctions &. and ^: directly, using the conjunction :. (obverse). The result of u :. v is a verb that is equivalent to u with an assigned obverse v.

In general, the term obverse is used instead of inverse, since the defined obverse need not be a true inverse, indeed it may be an unrelated verb.

For example:

   %: (*:2) + (*:5)          NB. square root of 2^2 + 5^2
5.38516
    
   2 + &. *: 5               NB. same
5.38516
   
   2  +&.(*: :. (^&1r2)) 5   NB. same (inverse of *: is square root)
5.38516
   
   2  +&.(*: :. (^&1r3)) 5   NB. using cube root as obverse
3.07232

Hex

Now lets take a closer look at the definition of hex:

   dfh=. 16&#. @ ('0123456789ABCDEF'&i.)

   hex=. &. dfh

The inverse of '0123456789ABCDEF'&i. is:

   { & '0123456789ABCDEF'

while the inverse of 16&#. is:

   16 16 ... 16 &#:  

with as many 16's as required.

Also, the inverse of f @ g is g-1 @ f-1 , hence the inverse of dfh can be calculated.

For any verb f:

   f hex x <=>  f &. dfh x  <=>  dfh-1 f dfh x