User:Devon McCormick/IdeasForJIn5Minutes/FiveTakes

From J Wiki
Jump to: navigation, search

Language Slapdown, J in 5 minutes, short introduction


Here are some preliminary ideas for introducing J to a technical audience as part of the Language Slapdown introduced here.

Take 1

My very first attempt went overboard on the mandatory "Hello World" example.

Before I give the "Hello, World" example, I'd like to explain a little about the language.

   i. 3 4     NB. "i." is a verb which acts on the noun "3 4".
0 1  2  3
4 5  6  7
8 9 10 11

   +/ i. 3 4
12 15 18 21
NB. "/" is an adverb which applies the verb "+" to the
NB.  noun resulting from the evaluation of "i. 3 4".

Here are examples of "Hello, World!" in J:

   'Hello, World!'   NB. Not a "program"  $(H i (Bs a noun, not a verb.
Hello, World!

   helloWorld=: 'Hello, World!'  NB. Not a verb, assigns name to noun.
   helloWorld                    NB. Immediate execution: displays value
Hello, World!

   helloWorld=: 3 : '''Hello, World!'''  NB. Simple verb definition
   helloWorld              NB. Without argument, displays "value".
3 : '''Hello, World!'''
   helloWorld ''           NB. Verb applied to noun gives (noun) result.
Hello, World!

   helloWorld=: 3 : 0      NB. Multi-line verb definition: let's do more.
   if. ' '={.0$y do. 'Hello, World!'             NB. Character argument or
   else. ('Hello, World'),('s'#~1~:{.y),'!' end. NB. numeric argument
)
   helloWorld ''               NB. Empty, character argument
Hello, World!
   helloWorld 1                NB. Numeric arguments one-at-a-time,
Hello, World!
   helloWorld 2
Hello, Worlds!
   helloWorld each 1;2;''      NB. or multiple arguments at once
+-------------+--------------+-------------+
|Hello, World!|Hello, Worlds!|Hello, World!|
+-------------+--------------+-------------+
   each                        NB. Definition of "each" adverb.
&.>
   helloWorld2=: helloWorld"0  NB. Version 2 works on scalar elements,
   helloWorld 1 2              NB. not entire argument as original.
Hello, World!
   helloWorld2 1 2
Hello, World!
Hello, Worlds!
helloWorld=: 3 : 0      NB. Multi-line definition - do more.
   if. ' '={.0$y do. 'Hello, "',(,y),'" world!' NB. Character argument or
   else. num=. ":{.y                            NB. numeric argument.
       ('Hello, ',num,' world'),('s'#~1~:{.y),'!' end.
)
   helloWorld2 i.2 3
Hello, 0 worlds!
Hello, 1 world!
Hello, 2 worlds!

Hello, 3 worlds!
Hello, 4 worlds!
Hello, 5 worlds!
   $helloWorld2 i.2 3      NB. Shape of argument prefixes shape of result.
2 3 16
   $helloWorld2 i.2 3 4    NB. Lengthens because of 2-digit numbers.
2 3 4 17
   helloWorld2 each 'HI';1 2;i.2 3
+-----------------+----------------+----------------+
|Hello, "H" world!|Hello, 1 world! |Hello, 0 worlds!|
|Hello, "I" world!|Hello, 2 worlds!|Hello, 1 world! |
|                 |                |Hello, 2 worlds!|
|                 |                |                |
|                 |                |Hello, 3 worlds!|
|                 |                |Hello, 4 worlds!|
|                 |                |Hello, 5 worlds!|
+-----------------+----------------+----------------+

Take 2

This time, I attempt to introduce more basic concepts about the language and minimize the "Hello World" example because it's such a trivial program that it can scarcely speak to the strengths of J.

   (3 : '''Hello, world!''') ''  NB. Anonymous function on empty argument.
Hello, world!

My thought here is to introduce a couple of basic elements of the J vocabulary to lead into showing a semi-realistic example of a powerful adverb.

   i. 3 4     NB. "i." is a verb which acts on the noun "3 4".
0 1  2  3
4 5  6  7
8 9 10 11

   +/ i. 3 4  NB. "/" is an adverb which applies the verb "+" to the
12 15 18 21   NB.  noun resulting from the evaluation of "i. 3 4".
   */ i. 3 4  NB. Use "multiply" noun instead of "add".
0 45 120 231
{{
Another adverb example: the "key" adverb.  First, let's define some nouns with data on holdings - ''hld'' - and the titles of each column - ''hldtit''.
}}
   'hldtit hld'=: split <;._1 &>TAB,&.><;._2 ] 0 : 0
Account	Ticker	Amount
001	AAPL	100
002	MSFT	200
003	IBM	300
001	MSFT	1000
002	PTY	2000
003	MSFT	3000
001	IBM	10000
002	AAPL	20000
003	AAPL	30000
)
hld=: (".&.>2{hld) 2}hld=: |:hld    NB. Columns to rows and convert numeric row to numbers.

Here's what these two nouns look like - we simply enter their names to display their values:

   hldtit
+----+---+---+
|Acct|Tkr|Amt|
+----+---+---+

   hld
+----+----+---+----+----+----+-----+-----+-----+
|001 |002 |003|001 |002 |003 |001  |002  |003  |
+----+----+---+----+----+----+-----+-----+-----+
|AAPL|MSFT|IBM|MSFT|PTY |MSFT|IBM  |AAPL |AAPL |
+----+----+---+----+----+----+-----+-----+-----+
|100 |200 |300|1000|2000|3000|10000|20000|30000|
+----+----+---+----+----+----+-----+-----+-----+

Here's what we might do with them: first, look up values by the column label.

   hldtit i. <'Tkr'              NB. Index of the "Ticker" column ,T
 (B1
   1{hld                         NB. Data in that column:
+----+----+---+----+---+----+---+----+----+
|AAPL|MSFT|IBM|MSFT|PTY|MSFT|IBM|AAPL|AAPL|
+----+----+---+----+---+----+---+----+----+
   hld{~hldtit i. <'Tkr'         NB. Combine the expressions:
+----+----+---+----+---+----+---+----+----+
|AAPL|MSFT|IBM|MSFT|PTY|MSFT|IBM|AAPL|AAPL|
+----+----+---+----+---+----+---+----+----+

Now, use key adverb "/." to sum the amounts by ticker and append the column text column-wise:

   (hld{~hldtit i. <'Tkr') (([: ~. [) ,. +&.>/ /.) hld{~hldtit i. <'Amt'
+----+-----+
|AAPL|50100|
+----+-----+
|MSFT|4200 |
+----+-----+
|IBM |10300|
+----+-----+
|PTY |2000 |
+----+-----+

Do the same with a different key value to sum by account:

   (hld{~hldtit i. <'Acct') (([: ~. [) ,. +&.>/ /.) hld{~hldtit i. <'Amt'
+---+-----+
|001|11100|
+---+-----+
|002|22200|
+---+-----+
|003|33300|
+---+-----+

But since "key" is an adverb, we can do things other than summation, like concatenation:

   (hld{~hldtit i. <'Acct') (([: ~. [) ,. , /.) hld{~hldtit i. <'Tkr'
+---+----+----+----+
|001|AAPL|MSFT|IBM |
+---+----+----+----+
|002|MSFT|PTY |AAPL|
+---+----+----+----+
|003|IBM |MSFT|AAPL|
+---+----+----+----+

Take 3

Here I go back to beating up "Hello World".

   (3 : '''Hello, world!''') ''  NB. Anonymous function on empty argument.
Hello, world!

If the spec for the "Hello, world" program really mandates it to be a niladic function (one that takes no argument) with a constant result, isn't this naturally a noun (data) rather than a verb (function)?

Here are some variations on this theme. First, start with variants for the first and last word:

   ('Hello';'Hi';'Yo');(<', ');<('world';'everybody'),&.>'!'
+-------------+----+-------------------+
|+-----+--+--+|+--+|+------+----------+|
||Hello|Hi|Yo|||, |||world!|everybody!||
|+-----+--+--+|+--+|+------+----------+|
+-------------+----+-------------------+

Then show all combos:

   {('Hello';'Hi';'Yo');(<', ');<('world';'everybody'),&.>'!'
+-----------------+---------------------+
|+-----+--+------+|+-----+--+----------+|
||Hello|, |world!|||Hello|, |everybody!||
|+-----+--+------+|+-----+--+----------+|
+-----------------+---------------------+
|+--+--+------+   |+--+--+----------+   |
||Hi|, |world!|   ||Hi|, |everybody!|   |
|+--+--+------+   |+--+--+----------+   |
+-----------------+---------------------+
|+--+--+------+   |+--+--+----------+   |
||Yo|, |world!|   ||Yo|, |everybody!|   |
|+--+--+------+   |+--+--+----------+   |
+-----------------+---------------------+

Then, for neatness, remove the inner boxing:

   ;&.>{('Hello';'Hi';'Yo');(<', ');<('world';'everybody'),&.>'!'
+-------------+-----------------+
|Hello, world!|Hello, everybody!|
+-------------+-----------------+
|Hi, world!   |Hi, everybody!   |
+-------------+-----------------+
|Yo, world!   |Yo, everybody!   |
+-------------+-----------------+

Introduce the start of the grammatical hierarchy:

   i. 3 4     NB. "i." is a verb which acts on the noun "3 4".
0 1  2  3
4 5  6  7
8 9 10 11

   +/ i. 3 4  NB. "/" is an adverb which applies the verb "+" to the
12 15 18 21   NB.  noun resulting from the evaluation of "i. 3 4".
   */ i. 3 4  NB. Apply a different verb to get the product of columns.
0 45 120 231

   (+`*)/ i. 3 4     NB. Can tie verbs together in sequence.
32 46 62 80
   (+/%#) i. 3 4     NB. Can apply verb train down columns
4 5 6 7
   (+/%#)"1 i. 3 4   NB. or across rows.
1.5 5.5 9.5

   applyRC=: 1 : '(u y);u"1 y'  NB. Apply arbitrary verb to columns and rows.
   +/ applyRC i. 3 4            NB. Sum rows and columns
+-----------+-------+
|12 15 18 21|6 22 38|
+-----------+-------+
   (+/%#) applyRC i. 3 4        NB. Average rows and columns
+-------+-----------+
|4 5 6 7|1.5 5.5 9.5|
+-------+-----------+

Take 4

Taking a different tack by demonstrating the power available from defining one's own adverb.

Maybe some examples using this user-defined adverb?

generalWalkTree=: 1 : 0
   (1 0) u generalWalkTree y  NB. Default: breadth-first, flattened result.
:
   ct=. 0 [ rr=. '' [ stack=. ,boxopen y [ x=. 2{.x
   ctr=. (0{x){_1 0           NB. First we build the stack.
   while. ct<#stack do.                           NB. Get subdir names:
       subds=. ((('d'e.&>4{"1])#0{"1])@:(1!:0@<)) (>ctr{stack),'\*'
       subds=. subds (],&.>'\',&.>[) ctr{stack    NB. -> full path names
       if. 0{x do. stack=. stack,subds            NB. Breadth or
       else.       stack=. subds,stack  end.      NB.  depth first
       ctr=. ctr+(0{x){_1 1 [ ct=. >:ct           NB. Go forward or backward
   end.
   dpth=. (]-<./)'\'+/ . =&>stack

   if. 1{x do. ;&.>(<:~.dpth) depthEnc dpth </. u&.>stack  NB. Preserve tree
   else.       u&.>stack              end.                 NB.  or flatten it.
NB.EG ([:;2{"1 [:dir '*',~],'\'-.{:) generalWalkTree 'C:\' NB. All file sizes
)

Let's define a verb to do some things to files in a directory:

workOnDir=: 3 : 0
   1!:44 y [ cfgfl=. 'test.cfg'           NB. Remove "version = ,T" (B line from
   if. fexist cfgfl do. fl=. f2v cfgfl    NB. the config file.
       rmln=. -.((<'version')+./ . E. &>tolower&.>fl) *. (<'=')+./ . E. &>fl
       (rmln#fl) v2f cfgfl [ ferase cfgfl end.
   if. 'output'-:>_1{a:-.~<;._1 '\',y do. NB. Remove *.txt files from output dir
           if. 0<#fls=. fls#~-.ferase&>fls=. 0{"1 dir '*.txt' do.
               smoutput 'In ',y,', failed to erase: '
               smoutput ' ','.',~punclist fls end.
   end.
)

Use this verb, starting at a particular directory and working down to all sub-directories.

   startdir=. 'C:\SP\EvalEng\Win\4.3Alpha3\'
   6!:2 'rr=. workOnDir generalWalkTree startdir'
0.75665196
   0*./ . =#&>rr                         NB. All results of zero-length?
1
   $rr                                   NB. How many directories did we visit?
116
   1!:43''                               NB. Where did we end up?
C:\SP\EvalEng\Win\4.3Alpha3\bin\Evaluator4.3Alpha3\SYNTHETICDEALS\queue\hold_area

It was generally agreed that this was far too much J code and too little explanation to be useful.

Take 5

[Things are starting to coalesce with this attempt.]

   (3 : '''Hello, world!''') ''  NB. Anonymous function on empty argument.
Hello, world!
   'Hello, world!'               NB. Ought to be simply constant string.
Hello, world!

Basic beginnings of J's grammatical hierarchy:

   i. 3 4      NB. "i." is a verb which acts on the noun "3 4".
0 1  2  3
4 5  6  7
8 9 10 11

   + / i. 3 4  NB. "/" is an adverb which applies the verb "+" across the
12 15 18 21    NB.  noun resulting from the evaluation of "i. 3 4".
   * / i. 3 4  NB. Apply a different verb to get the product of rows.
0 45 120 231

Digression on some aspects of array handling:

   (+`*) /  i. 3 4   NB. Can tie verbs together in sequence.
32 46 62 80          NB. 32=0+4*8; 46=1+5*9, etc.
   (+/%#)   i. 3 4   NB. Can apply verb train down columns
4 5 6 7
   (+/%#)"1 i. 3 4   NB. or across rows.
1.5 5.5 9.5

Back to grammar to highlight a simplifying rule: just as "verb + noun" ? new noun, "verb + adverb" ? new verb. So,

   Sum=: +/ [ Prod=: */                NB. Name some compound verbs
   AvgCol=: Avg"1 [ Avg=: +/%#         NB. Hidden in name vs. explicit "1.
   (Sum ; Prod ; Avg ; AvgCol) i. 3 4  NB. Verb train
+-----------+------------+-------+-----------+
|12 15 18 21|0 45 120 231|4 5 6 7|1.5 5.5 9.5|
+-----------+------------+-------+-----------+

Some more on array handling:

   +/ \ i. 3 4                         NB. Scan "\" ? Cumulative sum
 0  1  2  3                            NB. (+/0),(+/1),(+/2),(+/3)
 4  6  8 10                            NB. (+/0 4),(+/1 5),(+/2 6),(+/3 7)
12 15 18 21                            NB. (+/0 4 8),(+/1 5 9),(+/2 6 10), ,T
 (B   2 +/ \ i.4 4                        NB. "2": Sum (overlapping) pairs
 4  6  8 10
12 14 16 18
20 22 24 26
   _2 +/ \ i.4 4                       NB. "_2": Sum (non-overlapping pairs)
 4  6  8 10
20 22 24 26

Continuing up the grammatical hierarchy to show user-defined adverb:

   applyRC=: 1 : '(u y);u"1 y'  NB. Apply arbitrary verb to columns and rows.
   +/ applyRC i. 3 4            NB. Sum rows and columns
+-----------+-------+
|12 15 18 21|6 22 38|
+-----------+-------+
   (+/%#) applyRC i. 3 4        NB. Average rows and columns
+-------+-----------+
|4 5 6 7|1.5 5.5 9.5|
+-------+-----------+

Finally, the last grammatical element: a conjunction takes two verbs as its argument:

   showMM=: 4 : '(''''; y),:x;x +/ . * y'        NB. Show elements of matrix multiply
   ]idy4=. =/~i.4                                NB. 4x4 Identity mat
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
   idy4 showMM i. 4 4
+-------+-----------+
|       | 0  1  2  3|
|       | 4  5  6  7|
|       | 8  9 10 11|
|       |12 13 14 15|
+-------+-----------+
|1 0 0 0| 0  1  2  3|
|0 1 0 0| 4  5  6  7|
|0 0 1 0| 8  9 10 11|
|0 0 0 1|12 13 14 15|
+-------+-----------+
   showDotConj=: 2 : '(''''; ]),:[;[ x/ . y ]'  NB. Show generalized dot conjunction
   idy4 (+ showDotConj *) i. 4 4
+-------+-----------+
|       | 0  1  2  3|
|       | 4  5  6  7|
|       | 8  9 10 11|
|       |12 13 14 15|
+-------+-----------+
|1 0 0 0| 0  1  2  3|
|0 1 0 0| 4  5  6  7|
|0 0 1 0| 8  9 10 11|
|0 0 0 1|12 13 14 15|
+-------+-----------+