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|
+-------+-----------+