Here are the results of an exercise using some simple but cute

functions to learn J. The results were personally quite

rewarding and may be of interest.

I did not "catch on" to J quickly. However, that is a personal

statement about me, not about J. My goal has been to become

familiar with large parts of J. So, considering the richness

of the language and my unfamiliarity with the development of J

concepts (going back many years), I feel that the time has not

been inappropriately long. (Even a restricted subset makes for

a very powerful programming language, but many among us insist

on learning the whole thing, which is not unreasonable.) Also,

I feel my familiarity and years of "internalizing" APL in

various dialects has made it more difficult (a situation that

has in fact been reported by others.) The following exercise

turned out unexpectedly to be a really helpful learning

exercise.

As an exercise in learning J, I translated two simple functions

taken from the Toronto Toolkit, from APL (standard APL). One

function returns the roman numeral equivalent of an arabic

number, the other is the "inverse", giving the arabic

equivalent of a roman numeral.

First I translated the functions. They were simple functions

of several lines. (By the way, has anyone made a little

translation table of APL equivalents of the common functions

and idioms for use in translating from APL to J? Studies have

shown that certain functions and idioms are very common in APL

functions --- the 80/20 "rule".) If anyone wants to see mine,

send me a line.

For those "translation hackers" who love horror stories about

rewrites, I will mention that even in these small functions I

found some "wierd" APL code. For example, what do you think

this meant?

(in origin 1)(actually it doesn't matter)

(a,0)[1+ {iota} {rho} a]

If you guessed the following ...

1 {drop} a,0

... then you guessed what I guessed!! I wonder if I'll ever

find out how that got in there! It worked, though.

Anyway, the J functions were straightforward translations of

the algorithms, allowing for changing from origin 1 to origin

0, removing "wierd" phrases (see above), and removing some

parameter checking (for simplicity).

roman 16

xvi

roman 1995

mcmxcv

arabic 'xvi'

16

arabic 'mcmxcv'

1995

Now the original functions expected single numbers only, no

lists or matrices.

Then suddenly I realized I could use "the power of J". All

of a sudden the stuff I was learning about rank operator and

I could easily apply the functions (now called verbs) to any

array!

9!:7 '+++++++++|-'

roman"0 i.10

i

ii

iii

iv

v

vi

vii

viii

ix

NB. Let's box each result for a neat one-line display.

+-+--+---+----+---+--+---+----+-----+---+

|x|xi|xii|xiii|xiv|xv|xvi|xvii|xviii|xix|

+-+--+---+----+---+--+---+----+-----+---+

NB. Same idea for several multi-character arguments.

each =. &.>

arabic each 'xvi';'xxx';'mcmxcv'

+--+--+----+

|16|30|1995|

+--+--+----+

NB. This next part took a little experimentation to

NB. figure out how to return an unboxed result

NB. There are other ways but I wanted to play with

NB. the power of adverb operators.

(arabic &: > " 0) 'xvi';'xxx';'mcmxcv'

16 30 1995

every =. 1 : 'x. &: > " 0'

arabic every 'xvi';'xxx';'mcmxcv'

16 30 1995

NB. Then I got another idea. I mentionned I had always

NB. considered "roman" and "arabic" as inverses ...

roman 2001

mmi

arabic roman 2001

2001

roman arabic 'mi'

mi

NB. Now I could show this using the

NB. Power conjunction (operator).

NB. Define a function "roman" with inverse "arabic"

f =. roman :. arabic

f 16

xvi

NB. The power _1 is the inverse function, as is usual using

NB. power notation.

f^:_1 'xvi'

16

f^:_1 f 16

16

NB. This is fun. I like J.

NB. The text of the functions.

roman

+-+-+---------------------------------------------------------+

|3|:|NB. returns roman numeral equivalent for arabic number y.|

| | |NB. highest number in domain is 3999 |

| | |antibase =. #: |

| | |y =. , y. |

| | |m =. 3 3 3 3,1 3 3 3,1 1 3 3,1 1 1 3,1 0 3 3,0 3 3 3 |

| | |m =. 10 4 $ m, 0 1 3 3, 0 1 1 3, 0 1 1 1, 1 _1 3 3 |

| | |a =. ,(10 10 10 10 antibase y){m |

| | |(_1 + (a ~: 3) # a + 2 * <. 0.25 * i. 16) { 'mdclxvi' |

+-+-+---------------------------------------------------------+

arabic

+-+-+---------------------------------------------------------+

|3|:|NB. returns arabic number equivalent for roman numeral y.|

| | |NB. arabic is type numeric (base 10), roman is character |

| | |gte =. >: NB. (greater than or equal) |

| | |drop =. }. |

| | |a =. ('ivxlcdm' i. y.) { 1 5 10 50 100 500 1000 |

| | |+/ a * _1 + 2 * a gte 1 drop a,0 |

+-+-+---------------------------------------------------------+

--RL