J (Programming language)

J is an array programming language, claiming itself an APL successor.

Basics

'hello, worms'
unimplemented! (fixed-width){:type "fixed-width", :affiliated {:results ""}, :value "'hello, worms'", :position {:start {:line 17, :column 1, :offset 388}, :end {:line 17, :column 17, :offset 404}}}

Terminology

verb

A function. Verbs only come in two varieties, monadic (unary) and dyadic (binary).

operator

A higher-order function that computes functions from functions.

Adverb

A monadic operator.

monad

A unary verb.

dyad

A binary verb.

rank

The number of dimensions an array has. A scalar is rank-0, an array of scalars is rank-1, an XƗY table is rank-2, an XƗYƗZ table is rank-3, ...

shape

The list of an array's dimensions. 0 0 0 has shape 3, 2 3$0 has shape 2 3, etc. The shape of an object x is equal to #$x.

Syntax and evaluation order

J, like other array languages, only evaluates right-to-left — entirely homogeneous operator precedence. Every monad extends as far to the right as possible, and every dyad is right-associative.

2*3+4
(2*3)+4
unimplemented! (fixed-width){:type "fixed-width", :affiliated {:results ""}, :value "14\n10", :position {:start {:line 43, :column 1, :offset 1336}, :end {:line 44, :column 5, :offset 1345}}}

This tradition starts with APL.

Basic operations

Most basic verbs (functions) in J are overloaded to apply between scalars, map over arrays, and apply pointwise between arrays.

2*3
2*1 2 3
1 0 1*1 2 3
0 1*1 2 3
unimplemented! (fixed-width){:type "fixed-width", :affiliated {:results ""}, :value "6\n2 4 6\n1 0 3\nlength error, executing dyad *", :position {:start {:line 60, :column 1, :offset 1602}, :end {:line 63, :column 33, :offset 1654}}}

Some other verbs:

2<1 2 3 4
*:4       NB. Square function
25%5      NB. Division
#1 0 1 0  NB. "Tally" (length/count)
unimplemented! (fixed-width){:type "fixed-width", :affiliated {:results ""}, :value "0 0 1 1\n16\n5\n4", :position {:start {:line 75, :column 1, :offset 1811}, :end {:line 78, :column 4, :offset 1833}}}

/

/ is an adverb, akin to a fold or reduce operator. J people call it insert.

*/1 2 3
unimplemented! (fixed-width){:type "fixed-width", :affiliated {:results ""}, :value "6", :position {:start {:line 89, :column 1, :offset 1970}, :end {:line 89, :column 4, :offset 1973}}}

Example: array equality

Comparing arrays lifts the test pointwise:

x=:1 2 3 4
y=:1 2 7 4
x=y
unimplemented! (fixed-width){:type "fixed-width", :affiliated {:results ""}, :value "1 1 0 1", :position {:start {:line 102, :column 1, :offset 2110}, :end {:line 102, :column 10, :offset 2119}}}

One could reduce this to a single boolean with a fold:

x=:1 2 3 4
y=:1 2 7 4
x=y
=/x=y
x=x
=/x=x
unimplemented! (fixed-width){:type "fixed-width", :affiliated {:results ""}, :value "1 1 0 1\n0\n1 1 1 1\n1", :position {:start {:line 116, :column 1, :offset 2255}, :end {:line 119, :column 4, :offset 2282}}}

Assignments

x=:2 3 4
x
unimplemented! (fixed-width){:type "fixed-width", :affiliated {:results ""}, :value "2 3 4", :position {:start {:line 129, :column 1, :offset 2347}, :end {:line 129, :column 8, :offset 2354}}}

A terse reference list of basic verbs

The names listed are not those commonly-accepted. This is for my own personal recollection. }:3

unimplemented! (table){:type "table", :table-type "org", :tblfm "", :contents-begin 2495, :contents-end 3271, :position {:start {:line 135, :column 1, :offset 2495}, :end {:line 150, :column 1, :offset 3271}}, :children ([:details [:summary {:style {:font-family "IBM Plex Sans"}} ("unimplemented!" " (" [:code "table-row"] ")")] [:samp {:style {:overflow "scroll", :display "block", :white-space "pre"}} "{:type \"table-row\",\n :row-type \"standard\",\n :contents-begin 2496,\n :contents-end 2544,\n :position\n {:start {:line 135, :column 1, :offset 2495},\n :end {:line 135, :column 50, :offset 2544}},\n :children\n ([:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 2497,\\n :contents-end 2499,\\n :position\\n {:start {:line 135, :column 2, :offset 2496},\\n :end {:line 135, :column 7, :offset 2501}},\\n :children (\\\"op\\\")}\\n\"]]\n [:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 2502,\\n :contents-end 2507,\\n :position\\n {:start {:line 135, :column 7, :offset 2501},\\n :end {:line 135, :column 22, :offset 2516}},\\n :children (\\\"monad\\\")}\\n\"]]\n [:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 2517,\\n :contents-end 2521,\\n :position\\n {:start {:line 135, :column 22, :offset 2516},\\n :end {:line 135, :column 50, :offset 2544}},\\n :children (\\\"dyad\\\")}\\n\"]])}\n"]] [:details [:summary {:style {:font-family "IBM Plex Sans"}} ("unimplemented!" " (" [:code "table-row"] ")")] [:samp {:style {:overflow "scroll", :display "block", :white-space "pre"}} "{:type \"table-row\",\n :row-type \"rule\",\n :contents-begin 2546,\n :contents-end 2546,\n :position\n {:start {:line 136, :column 1, :offset 2545},\n :end {:line 136, :column 50, :offset 2594}},\n :children nil}\n"]] [:details [:summary {:style {:font-family "IBM Plex Sans"}} ("unimplemented!" " (" [:code "table-row"] ")")] [:samp {:style {:overflow "scroll", :display "block", :white-space "pre"}} "{:type \"table-row\",\n :row-type \"standard\",\n :contents-begin 2596,\n :contents-end 2646,\n :position\n {:start {:line 137, :column 1, :offset 2595},\n :end {:line 137, :column 52, :offset 2646}},\n :children\n ([:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 2597,\\n :contents-end 2600,\\n :position\\n {:start {:line 137, :column 2, :offset 2596},\\n :end {:line 137, :column 9, :offset 2603}},\\n :children ([:code \\\",\\\"])}\\n\"]]\n [:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 2617,\\n :contents-end 2617,\\n :position\\n {:start {:line 137, :column 9, :offset 2603},\\n :end {:line 137, :column 24, :offset 2618}},\\n :children nil}\\n\"]]\n [:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 2619,\\n :contents-end 2625,\\n :position\\n {:start {:line 137, :column 24, :offset 2618},\\n :end {:line 137, :column 52, :offset 2646}},\\n :children (\\\"append\\\")}\\n\"]])}\n"]] [:details [:summary {:style {:font-family "IBM Plex Sans"}} ("unimplemented!" " (" [:code "table-row"] ")")] [:samp {:style {:overflow "scroll", :display "block", :white-space "pre"}} "{:type \"table-row\",\n :row-type \"standard\",\n :contents-begin 2648,\n :contents-end 2698,\n :position\n {:start {:line 138, :column 1, :offset 2647},\n :end {:line 138, :column 52, :offset 2698}},\n :children\n ([:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 2649,\\n :contents-end 2652,\\n :position\\n {:start {:line 138, :column 2, :offset 2648},\\n :end {:line 138, :column 9, :offset 2655}},\\n :children ([:code \\\"<\\\"])}\\n\"]]\n [:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 2656,\\n :contents-end 2659,\\n :position\\n {:start {:line 138, :column 9, :offset 2655},\\n :end {:line 138, :column 24, :offset 2670}},\\n :children (\\\"box\\\")}\\n\"]]\n [:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 2671,\\n :contents-end 2673,\\n :position\\n {:start {:line 138, :column 24, :offset 2670},\\n :end {:line 138, :column 52, :offset 2698}},\\n :children (\\\"LT\\\")}\\n\"]])}\n"]] [:details [:summary {:style {:font-family "IBM Plex Sans"}} ("unimplemented!" " (" [:code "table-row"] ")")] [:samp {:style {:overflow "scroll", :display "block", :white-space "pre"}} "{:type \"table-row\",\n :row-type \"standard\",\n :contents-begin 2700,\n :contents-end 2750,\n :position\n {:start {:line 139, :column 1, :offset 2699},\n :end {:line 139, :column 52, :offset 2750}},\n :children\n ([:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 2701,\\n :contents-end 2705,\\n :position\\n {:start {:line 139, :column 2, :offset 2700},\\n :end {:line 139, :column 9, :offset 2707}},\\n :children ([:code \\\">.\\\"])}\\n\"]]\n [:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 2708,\\n :contents-end 2712,\\n :position\\n {:start {:line 139, :column 9, :offset 2707},\\n :end {:line 139, :column 24, :offset 2722}},\\n :children (\\\"ceil\\\")}\\n\"]]\n [:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 2723,\\n :contents-end 2726,\\n :position\\n {:start {:line 139, :column 24, :offset 2722},\\n :end {:line 139, :column 52, :offset 2750}},\\n :children (\\\"max\\\")}\\n\"]])}\n"]] [:details [:summary {:style {:font-family "IBM Plex Sans"}} ("unimplemented!" " (" [:code "table-row"] ")")] [:samp {:style {:overflow "scroll", :display "block", :white-space "pre"}} "{:type \"table-row\",\n :row-type \"standard\",\n :contents-begin 2752,\n :contents-end 2802,\n :position\n {:start {:line 140, :column 1, :offset 2751},\n :end {:line 140, :column 52, :offset 2802}},\n :children\n ([:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 2753,\\n :contents-end 2756,\\n :position\\n {:start {:line 140, :column 2, :offset 2752},\\n :end {:line 140, :column 9, :offset 2759}},\\n :children ([:code \\\"/\\\"])}\\n\"]]\n [:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 2773,\\n :contents-end 2773,\\n :position\\n {:start {:line 140, :column 9, :offset 2759},\\n :end {:line 140, :column 24, :offset 2774}},\\n :children nil}\\n\"]]\n [:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 2775,\\n :contents-end 2779,\\n :position\\n {:start {:line 140, :column 24, :offset 2774},\\n :end {:line 140, :column 52, :offset 2802}},\\n :children (\\\"fold\\\")}\\n\"]])}\n"]] [:details [:summary {:style {:font-family "IBM Plex Sans"}} ("unimplemented!" " (" [:code "table-row"] ")")] [:samp {:style {:overflow "scroll", :display "block", :white-space "pre"}} "{:type \"table-row\",\n :row-type \"standard\",\n :contents-begin 2804,\n :contents-end 2854,\n :position\n {:start {:line 141, :column 1, :offset 2803},\n :end {:line 141, :column 52, :offset 2854}},\n :children\n ([:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 2805,\\n :contents-end 2808,\\n :position\\n {:start {:line 141, :column 2, :offset 2804},\\n :end {:line 141, :column 9, :offset 2811}},\\n :children ([:code \\\"{\\\"])}\\n\"]]\n [:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 2825,\\n :contents-end 2825,\\n :position\\n {:start {:line 141, :column 9, :offset 2811},\\n :end {:line 141, :column 24, :offset 2826}},\\n :children nil}\\n\"]]\n [:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 2827,\\n :contents-end 2832,\\n :position\\n {:start {:line 141, :column 24, :offset 2826},\\n :end {:line 141, :column 52, :offset 2854}},\\n :children (\\\"index\\\")}\\n\"]])}\n"]] [:details [:summary {:style {:font-family "IBM Plex Sans"}} ("unimplemented!" " (" [:code "table-row"] ")")] [:samp {:style {:overflow "scroll", :display "block", :white-space "pre"}} "{:type \"table-row\",\n :row-type \"standard\",\n :contents-begin 2856,\n :contents-end 2906,\n :position\n {:start {:line 142, :column 1, :offset 2855},\n :end {:line 142, :column 52, :offset 2906}},\n :children\n ([:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 2857,\\n :contents-end 2861,\\n :position\\n {:start {:line 142, :column 2, :offset 2856},\\n :end {:line 142, :column 9, :offset 2863}},\\n :children ([:code \\\"i.\\\"])}\\n\"]]\n [:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 2864,\\n :contents-end 2876,\\n :position\\n {:start {:line 142, :column 9, :offset 2863},\\n :end {:line 142, :column 24, :offset 2878}},\\n :children (\\\"range [0..n]\\\")}\\n\"]]\n [:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 2905,\\n :contents-end 2905,\\n :position\\n {:start {:line 142, :column 24, :offset 2878},\\n :end {:line 142, :column 52, :offset 2906}},\\n :children nil}\\n\"]])}\n"]] [:details [:summary {:style {:font-family "IBM Plex Sans"}} ("unimplemented!" " (" [:code "table-row"] ")")] [:samp {:style {:overflow "scroll", :display "block", :white-space "pre"}} "{:type \"table-row\",\n :row-type \"standard\",\n :contents-begin 2908,\n :contents-end 2958,\n :position\n {:start {:line 143, :column 1, :offset 2907},\n :end {:line 143, :column 52, :offset 2958}},\n :children\n ([:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 2909,\\n :contents-end 2912,\\n :position\\n {:start {:line 143, :column 2, :offset 2908},\\n :end {:line 143, :column 9, :offset 2915}},\\n :children ([:code \\\";\\\"])}\\n\"]]\n [:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 2929,\\n :contents-end 2929,\\n :position\\n {:start {:line 143, :column 9, :offset 2915},\\n :end {:line 143, :column 24, :offset 2930}},\\n :children nil}\\n\"]]\n [:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 2931,\\n :contents-end 2935,\\n :position\\n {:start {:line 143, :column 24, :offset 2930},\\n :end {:line 143, :column 52, :offset 2958}},\\n :children (\\\"link\\\")}\\n\"]])}\n"]] [:details [:summary {:style {:font-family "IBM Plex Sans"}} ("unimplemented!" " (" [:code "table-row"] ")")] [:samp {:style {:overflow "scroll", :display "block", :white-space "pre"}} "{:type \"table-row\",\n :row-type \"standard\",\n :contents-begin 2960,\n :contents-end 3010,\n :position\n {:start {:line 144, :column 1, :offset 2959},\n :end {:line 144, :column 52, :offset 3010}},\n :children\n ([:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 2961,\\n :contents-end 2964,\\n :position\\n {:start {:line 144, :column 2, :offset 2960},\\n :end {:line 144, :column 9, :offset 2967}},\\n :children ([:code \\\"=\\\"])}\\n\"]]\n [:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 2981,\\n :contents-end 2981,\\n :position\\n {:start {:line 144, :column 9, :offset 2967},\\n :end {:line 144, :column 24, :offset 2982}},\\n :children nil}\\n\"]]\n [:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 2983,\\n :contents-end 3008,\\n :position\\n {:start {:line 144, :column 24, :offset 2982},\\n :end {:line 144, :column 52, :offset 3010}},\\n :children (\\\"pointwise/scalar equality\\\")}\\n\"]])}\n"]] [:details [:summary {:style {:font-family "IBM Plex Sans"}} ("unimplemented!" " (" [:code "table-row"] ")")] [:samp {:style {:overflow "scroll", :display "block", :white-space "pre"}} "{:type \"table-row\",\n :row-type \"standard\",\n :contents-begin 3012,\n :contents-end 3062,\n :position\n {:start {:line 145, :column 1, :offset 3011},\n :end {:line 145, :column 52, :offset 3062}},\n :children\n ([:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 3013,\\n :contents-end 3017,\\n :position\\n {:start {:line 145, :column 2, :offset 3012},\\n :end {:line 145, :column 9, :offset 3019}},\\n :children ([:code \\\":*\\\"])}\\n\"]]\n [:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 3020,\\n :contents-end 3026,\\n :position\\n {:start {:line 145, :column 9, :offset 3019},\\n :end {:line 145, :column 24, :offset 3034}},\\n :children (\\\"square\\\")}\\n\"]]\n [:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 3061,\\n :contents-end 3061,\\n :position\\n {:start {:line 145, :column 24, :offset 3034},\\n :end {:line 145, :column 52, :offset 3062}},\\n :children nil}\\n\"]])}\n"]] [:details [:summary {:style {:font-family "IBM Plex Sans"}} ("unimplemented!" " (" [:code "table-row"] ")")] [:samp {:style {:overflow "scroll", :display "block", :white-space "pre"}} "{:type \"table-row\",\n :row-type \"standard\",\n :contents-begin 3064,\n :contents-end 3114,\n :position\n {:start {:line 146, :column 1, :offset 3063},\n :end {:line 146, :column 52, :offset 3114}},\n :children\n ([:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 3065,\\n :contents-end 3069,\\n :position\\n {:start {:line 146, :column 2, :offset 3064},\\n :end {:line 146, :column 9, :offset 3071}},\\n :children ([:code \\\"-:\\\"])}\\n\"]]\n [:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 3085,\\n :contents-end 3085,\\n :position\\n {:start {:line 146, :column 9, :offset 3071},\\n :end {:line 146, :column 24, :offset 3086}},\\n :children nil}\\n\"]]\n [:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 3087,\\n :contents-end 3106,\\n :position\\n {:start {:line 146, :column 24, :offset 3086},\\n :end {:line 146, :column 52, :offset 3114}},\\n :children (\\\"structural equality\\\")}\\n\"]])}\n"]] [:details [:summary {:style {:font-family "IBM Plex Sans"}} ("unimplemented!" " (" [:code "table-row"] ")")] [:samp {:style {:overflow "scroll", :display "block", :white-space "pre"}} "{:type \"table-row\",\n :row-type \"standard\",\n :contents-begin 3116,\n :contents-end 3166,\n :position\n {:start {:line 147, :column 1, :offset 3115},\n :end {:line 147, :column 52, :offset 3166}},\n :children\n ([:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 3117,\\n :contents-end 3121,\\n :position\\n {:start {:line 147, :column 2, :offset 3116},\\n :end {:line 147, :column 9, :offset 3123}},\\n :children ([:code \\\">:\\\"])}\\n\"]]\n [:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 3124,\\n :contents-end 3133,\\n :position\\n {:start {:line 147, :column 9, :offset 3123},\\n :end {:line 147, :column 24, :offset 3138}},\\n :children (\\\"successor\\\")}\\n\"]]\n [:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 3139,\\n :contents-end 3142,\\n :position\\n {:start {:line 147, :column 24, :offset 3138},\\n :end {:line 147, :column 52, :offset 3166}},\\n :children (\\\"GTE\\\")}\\n\"]])}\n"]] [:details [:summary {:style {:font-family "IBM Plex Sans"}} ("unimplemented!" " (" [:code "table-row"] ")")] [:samp {:style {:overflow "scroll", :display "block", :white-space "pre"}} "{:type \"table-row\",\n :row-type \"standard\",\n :contents-begin 3168,\n :contents-end 3218,\n :position\n {:start {:line 148, :column 1, :offset 3167},\n :end {:line 148, :column 52, :offset 3218}},\n :children\n ([:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 3169,\\n :contents-end 3172,\\n :position\\n {:start {:line 148, :column 2, :offset 3168},\\n :end {:line 148, :column 9, :offset 3175}},\\n :children ([:code \\\"#\\\"])}\\n\"]]\n [:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 3176,\\n :contents-end 3181,\\n :position\\n {:start {:line 148, :column 9, :offset 3175},\\n :end {:line 148, :column 24, :offset 3190}},\\n :children (\\\"tally\\\")}\\n\"]]\n [:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 3217,\\n :contents-end 3217,\\n :position\\n {:start {:line 148, :column 24, :offset 3190},\\n :end {:line 148, :column 52, :offset 3218}},\\n :children nil}\\n\"]])}\n"]] [:details [:summary {:style {:font-family "IBM Plex Sans"}} ("unimplemented!" " (" [:code "table-row"] ")")] [:samp {:style {:overflow "scroll", :display "block", :white-space "pre"}} "{:type \"table-row\",\n :row-type \"standard\",\n :contents-begin 3220,\n :contents-end 3270,\n :position\n {:start {:line 149, :column 1, :offset 3219},\n :end {:line 149, :column 52, :offset 3270}},\n :children\n ([:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 3221,\\n :contents-end 3224,\\n :position\\n {:start {:line 149, :column 2, :offset 3220},\\n :end {:line 149, :column 9, :offset 3227}},\\n :children ([:code \\\">\\\"])}\\n\"]]\n [:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 3228,\\n :contents-end 3233,\\n :position\\n {:start {:line 149, :column 9, :offset 3227},\\n :end {:line 149, :column 24, :offset 3242}},\\n :children (\\\"unbox\\\")}\\n\"]]\n [:details\n [:summary\n {:style {:font-family \"IBM Plex Sans\"}}\n (\"unimplemented!\" \" (\" [:code \"table-cell\"] \")\")]\n [:samp\n {:style {:overflow \"scroll\", :display \"block\", :white-space \"pre\"}}\n \"{:type \\\"table-cell\\\",\\n :contents-begin 3243,\\n :contents-end 3245,\\n :position\\n {:start {:line 149, :column 24, :offset 3242},\\n :end {:line 149, :column 52, :offset 3270}},\\n :children (\\\"GT\\\")}\\n\"]])}\n"]])}

On the naming of primitive verbs

Almost all of J's built-in verbs have names one or two characters long. If there is a second character, it is always (:) or (.). The colon or dot suffix is intended to imply some connection to the one-character name. E.g., square (*:) bears an obvious connection to multiplication (*).

Presented are some examples intended to illustrate the loose connection between uses of similarly-named verbs.

>

1>2          NB. Greater-than
3>.12        NB. Maximum
>.0.5        NB. Ceiling
>:3          NB. Increment
5>:4 5 6     NB. Greater-than or equal
unimplemented! (fixed-width){:type "fixed-width", :affiliated {:results ""}, :value "0\n12\n1\n4\n1 1 0", :position {:start {:line 168, :column 1, :offset 3907}, :end {:line 172, :column 8, :offset 3931}}}

Tables

Constructing a 2Ɨ3 table

Excess will be truncated:

2 3$0 1 2 3 4 5 6 7
unimplemented! (fixed-width){:type "fixed-width", :affiliated {:results ""}, :value "0 1 2\n3 4 5", :position {:start {:line 185, :column 1, :offset 4057}, :end {:line 186, :column 8, :offset 4072}}}

Insufficiency will be coped with by cycling:

2 3$0 1
unimplemented! (fixed-width){:type "fixed-width", :affiliated {:results ""}, :value "0 1 0\n1 0 1", :position {:start {:line 195, :column 1, :offset 4164}, :end {:line 196, :column 8, :offset 4179}}}

Tally

Tally counts the number of rows a table has:

#2 5$0
unimplemented! (fixed-width){:type "fixed-width", :affiliated {:results ""}, :value "2", :position {:start {:line 207, :column 1, :offset 4281}, :end {:line 207, :column 4, :offset 4284}}}

Bonding

double =: * & 2
double 2
unimplemented! (fixed-width){:type "fixed-width", :affiliated {:results ""}, :value "4", :position {:start {:line 217, :column 1, :offset 4359}, :end {:line 217, :column 4, :offset 4362}}}

    (f & k) y    means    y f k
    (k & f) y    means    k f y

Addons (libraries)

There are a number of official J libraries living under the jsoftware Github org.

Use on NixOS

J makes a lot of FHS-based assumptions that make packaging for Nix non-trivial. Perhaps I'll be the one to deal with that if I continue using J }:3.

In the meantime, the workaround isn't too bad [cite:@young2021workaround]:

1. Figure out where your J startup file is

The startup file is called startup.ijs, and lives in the directory returned by the following expression:

jpath'~config'
unimplemented! (fixed-width){:type "fixed-width", :affiliated {:results ""}, :value "/home/crumb/j9.5-user/config", :position {:start {:line 243, :column 1, :offset 5048}, :end {:line 243, :column 31, :offset 5078}}}

It is okay if the startup file doesn't yet exist; just create it!

2. Tell J where to find addons

Append this to your startup file:

SystemFolders_j_=:('addons';jpath'~user/addons'),SystemFolders_j_

3. Install your desired addons

Simply — though inelegantly — all that is left is to manually clone addons into the addons directory. E.g., for graphics/plot:

$ cd "$(jconsole <<< "jpath'~addons'")"
$ mkdir graphics
$ git clone git@github.com:jsoftware/graphics_plot.git graphics/plot

And load the library in jconsole like so:

load'plot'
unimplemented! (fixed-width){:type "fixed-width", :affiliated {:results ""}, :value "not found: /home/crumb/j9.5-user/addons/graphics/bmp/bmp.ijs\n|file name error in script, executing monad 0!:0\n|nonexistent file or invalid filename\n| 0!:0 y[4!:55<'y'\n|[-2] /home/crumb/j9.5-user/addons/graphics/plot/jzplot.ijs", :position {:start {:line 272, :column 1, :offset 5724}, :end {:line 276, :column 62, :offset 5966}}}

Oops — we need to manually install each dependency }:P. It's not fun, but it isn't so bad. So far, I've only had to install 3–4 dependencies (transitives included) for new addons.

Graphics

It appears many graphics-related things are only avaiable in the JQT IDE. Namely, wd and OpenGL.

References