├── .github └── README.md ├── QUICKSTART.ijs ├── abort-hanging-session.md ├── cut.md ├── iterating-over-locales.ijs └── understanding-j.md /.github/README.md: -------------------------------------------------------------------------------- 1 | ../understanding-j.md -------------------------------------------------------------------------------- /QUICKSTART.ijs: -------------------------------------------------------------------------------- 1 | NB. comment the rest of the line 2 | NB. run J in browser: https://jsoftware.github.io/j-playground/bin/html2 3 | NB. most important wiki page: https://code.jsoftware.com/wiki/NuVoc 4 | NB. this describes J9.4 5 | 6 | NB. J is an executable alternative mathematical notation 7 | - 2 NB. negate number; negative sign is an underscore! 8 | 1 - 2 NB. different function with same name: subtract 9 | 2 - NB. error: either 2 args or arg to the right 10 | 11 | NB. basic datatypes are strings and numbers 12 | 'strings may not be double quoted (")' 13 | 'escape single quote like so: '' by doubling it' 14 | _1 1j2 3.45 16bff _ NB. negative-integer complex float hex infinity 15 | 16 | NB. basic mathematical functions 17 | 2 + 3 NB. addition 18 | 2 - 3 NB. subtraction 19 | 2 * 3 NB. multiplication 20 | 3 % 2 NB. division 21 | 2 | 3 NB. remainder of 3%2 22 | 2 ^ 3 NB. 2 to the power of 3 23 | 3 %: 8 NB. 3rd root of 8 24 | 2 ^. 8 NB. log base 2 of 8 25 | 26 | NB. Arrays are the only datastructure: lists of lists of equal length 27 | NB. and type. There is no notation for higher dimensional arrays; only 28 | NB. for lists: just put the elements next to each other. The list of the 29 | NB. lengths of each dimension (nesting level) is called shape. 30 | 0 1 2 NB. list of 3 numbers 31 | (0 1 2) (3 4) NB. error: implicit joining does not work 32 | 0 1 2 , 3 4 NB. use function , to join lists 33 | # 1 2 3 NB. length (top level elements) of array 34 | i. 2 3 NB. produces array of given shape: 2 lists of 3 35 | 36 | NB. Strings are actually lists of characters; an empty string is often 37 | NB. used as an empty list! 38 | '' NB. empty list 39 | # '' NB. length 0 40 | 'string' , 1 2 NB. error: incompatible types 41 | '' , 1 2 NB. ok: new list still consists of one type only 42 | 43 | NB. Functions are executed in right to left order and are greedy (take 44 | NB. left argument if available). Use parentheses to influence that. 45 | # i. 3 2 NB. first i. on argument 3 2 then # on result 46 | # i. 5 - 2 NB. first - which takes both args, then i. then # 47 | 2 * 3 + 4 NB. 14 48 | (2*3) + 4 NB. 10 49 | 50 | NB. Single values are called scalars or atoms and may be treated as 51 | NB. arrays with an empty shape. They are different from arrays with 52 | NB. zeros in their shape or ones with a single atom: 53 | i. 2 3 NB. this array is displayed identical to this: 54 | i. 1 2 3 NB. but: shape (2 3) is not (1 2 3) 55 | i. '' NB. an atom not in a list has an empty shape 56 | i. 1 NB. it is not the same as here: a list with 1 atom 57 | i. 0 NB. nor the same as a list with 0 elements: no atoms 58 | i. 0 3 NB. a table with 0 lists of 3 elements: has no atoms 59 | 60 | NB. There is also the datatype box which is used to wrap other data 61 | NB. which allows it to be in the same array since now all elements have 62 | NB. type box... 63 | <3 NB. a number in a box 64 | <'string' NB. a string in a box 65 | 3 , 'string' NB. error 66 | (<3) , <'string' NB. ok 67 | 68 | NB. boxes have to be unpacked before working with them 69 | > (<3) NB. unpack box 70 | 1 + (<3) NB. error 71 | 1 + > (<3) NB. ok 72 | 73 | NB. From now on call functions which take and return nouns "verbs" of 74 | NB. which there are two types: verbs with one argument are monads and 75 | NB. verbs with two args are dyads. 76 | mymonad =:{{y - 1}} NB. right argument is called y 77 | mydyad =: {{x - y}} NB. left argument is called x 78 | mymonad 1 79 | 1 mymonad 2 NB. error: a monad only takes one arg 80 | 1 mydyad 2 81 | mydyad 1 NB. error: a dyad only takes one arg 82 | 83 | NB. One name (like -) can be a monad (like negate) and a dyad (like 84 | NB. subtract) at the same time. Which is used depends on how it is 85 | NB. invoked. 86 | ambi =: {{ 87 | echo (<'called with arg:'),( wont execute 119 | global =: 'foo' NB. interpreter doesn't show assignment return value 120 | echo global =:'glo' NB. but it can be used within an expression 121 | {{ NB. function scope: 122 | echo global NB. not found locally but globally -> global value 123 | global =: 'changed by outer function' 124 | local =. 'local' 125 | 126 | {{ NB. inner function's scope: 127 | echo 'global ', global 128 | global =: 'changed by inner function' 129 | echo local NB. no access to parent -> not found -> not executed 130 | local =. 'local2' 131 | }} '' NB. provide arg to immediately execute this function 132 | echo 'unchanged ', local 133 | NB. Had we used =: in inner function this would still print the 134 | NB. unchanged outer "local"'s value but a global variable "local" 135 | NB. would have been created (or modified if it existed). 136 | 137 | NB. control-structures use function scope: 138 | foo =. 0 139 | while. foo < 3 do. echo foo =. foo + 1 end. 140 | echo 'local foo changed from 0 to'; foo 141 | for. 1 2 3 do. echo 'no access to current value' end. 142 | for_var. 'abc' do. echo 'loop state'; var_index; var end. 143 | echo 'vars still exist thus this executes'; var_index; var 144 | for_var2. 'abcdef' do. 145 | if. var2 = 'b' do. continue. end. 146 | NB. note how it skips outputting 'b' 147 | echo 'current value: ', var2 148 | if. var2 = 'd' do. break. end. 149 | end. 150 | echo 'loop aborted thus var2 not reset to empty'; var2_index; var2 151 | }} '' 152 | echo 'global ', global 153 | echo local NB. not found in global scope -> not executed 154 | 155 | NB. Functions which may take and/or return other functions as arguments 156 | NB. are called modifiers. If they return a new function (most do so) it 157 | NB. has access to the original arguments of the modifier as u (left arg) 158 | NB. and v (right arg). u and v may also be called m and n respectively 159 | NB. to indicate that they are nouns. Due to the predetermined meaning 160 | NB. of certain names, get into the habit of only using *capital* single 161 | NB. letter variables! Modifiers are not ambivalent; with 2 original 162 | NB. arguments they are called conjunctions and those with 1 are called 163 | NB. adverbs. Note that adverbs take their argument from the left and 164 | NB. sequences of modifiers are processed left to right! 165 | mymod =: {{ NB. in old fn notation it would be (1 : 0) 166 | NB. This modifier takes 1 argument and thus is an adverb. It returns 167 | NB. an ambivalent function (the modifier is not ambivalent!) which 168 | NB. *) copies its argument to the other side thus becomes a dyad: 169 | y u y 170 | : 171 | NB. *) or (if called as a dyad) swaps its arguments 172 | y u x 173 | }} 174 | + mymod 2 NB. becomes: returnedFunc 2 which does 2+2 175 | 4 - mymod 1 NB. becomes: 4 returnedFunc 1 which does 1-4 176 | NB. this is exactly what builtin adverb ~ does: 177 | + ~ 2 178 | 4 - ~ 1 179 | NB. builtin adverb / inserts its verb between the items of its arg 180 | +/ 4 2 1 NB. same as 4 + 2 + 1 181 | -/ 4 2 1 NB. beware right to left execution: 4 - (2 - 1) 182 | NB. or if applied dyadically it combines every left and right elements 183 | 1 2 3 4 */ 1 2 3 4 NB. multiplication table 184 | NB. sequence of modifiers 185 | -~/ 4 2 1 NB. first: make fn which swaps args then: insert it 186 | 4 -~ 2 -~ 1 NB. equivalent 187 | (1 - 2) - 4 NB. equivalent 188 | 189 | NB. By default a function receives its whole argument. Conjunction " 190 | NB. can change that: It breaks the argument into pieces and calls the 191 | NB. verb on each piece individually. The size of the pieces is 192 | NB. determined by the right argument to " which is called the rank of 193 | NB. the verb and specifies how many dimensions the piece has. Default 194 | NB. ranks of builtins must be learnt! 195 | fn =: {{ frame is empty (atom) 207 | <"2 i.2 3 4 NB. pieces are shape 3 4 -> frame is shape 2 (list) 208 | <"1 i.2 3 4 NB. pieces are shape 4 -> frame is shape 2 3 (table) 209 | <"0 i.2 3 4 NB. pieces have empty shape -> frame is shape of arg 210 | 211 | NB. Dyads have 2 ranks, one for each side, which may differ from the 212 | NB. monadic rank. They pair the pieces from both sides by index, with 213 | NB. the special case that a single piece on a side is paired with every 214 | NB. piece from the other side individually. 215 | + b.0 NB. shows the 3 ranks: monadic, left, dyadic right 216 | 1 2 3 + 4 5 6 NB. thus pairs atoms 217 | 1 2 3 +"(0 0) 4 5 6 NB. equivalent 218 | 1 + 4 5 6 NB. left side has only one piece -> with each right 219 | 4 5 6 + 1 NB. right side has only one piece -> with each left 220 | 1 2 + 3 4 5 NB. error: cannot pair 2 pieces with 3 221 | bj =: {{(y}}"0 (2$< 3$<'shape: 5') 245 | NB. results are of shape (2) and are assembled into longer frame (2 3): 246 | >(2 3$<'shape 2') 247 | 248 | NB. Elements of different shape cannot be in the same array. However, 249 | NB. they can be converted to type box, which is always an atom (empty 250 | NB. shape). Another possibility is to make the shorter elements bigger 251 | NB. by appending some value, which J does automatically when unboxing or 252 | NB. assembling subresults into the final one: 253 | (<1),(<1 2 3) 254 | >(<1),(<1 2 3) NB. added 0s 255 | >(<1+i.2 2),(<1+i.3 3) 256 | {{<1+i.y}}"(0) 1 2 3 NB. results are all same shape -> no padding 257 | {{ 1+i.y}}"(0) 1 2 3 NB. here the shapes differ -> adds 0s as padding 258 | {{ 1+i.y,y}}"(0) 1 2 3 259 | 260 | NB. J gives sequences of verb which are not invoked (due to a missing 261 | NB. argument) special meaning and calls them trains: They create a new 262 | NB. verb which independently applies each odd numbered verb of the 263 | NB. sequence to its argument/s. The even numbered verbs are then used to 264 | NB. combine their neighbouring results from right to left: 265 | avg =: +/ % # NB. +/ and # on arg, then combine with % 266 | avg 1 2 3 4 267 | (+/ % #) 1 2 3 4 NB. same: exprssion in () does not execute -> train 268 | 2 (* % +) 3 NB. (2*3)%(2+3) 269 | 2 (- * * % +) 3 NB. (2-3)*((2*3)%(2+3)) 270 | 271 | NB. If a train is missing the last function because its length is even 272 | NB. it uses one of its arguments instead of the missing result. However, 273 | NB. they use the left argument only to replace the missing result, not 274 | NB. as second argument to other verbs! 275 | (- +/ % #) 1 2 3 4 NB. argument minus average (2.5) 276 | 2 (* -) 3 NB. 2*( -3) not 2*(2-3) 277 | 278 | NB. Instead, any verb which supplies the left argument to a combining 279 | NB. verb can be replaced by a noun! These verbs may also be replaced 280 | NB. by by [: which signals to its combining verb to ignore it and apply 281 | NB. monadically. Verbs [ and ] return the (if dyads: left or right 282 | NB. respectively) argument unchanged. 283 | 2 (2 * -) 3 NB. 2*(x-y) = 2*(2-3) 284 | 2 ([ * -) 3 NB. (x[y)*(x-y) = 2*(2-3) 285 | 2 (] * -) 3 NB. (x]y)*(x-y) = 3*(2-3) 286 | 2 ([ * [: - ]) 3 NB. (x[y)*( -(x]y)) = 2*( -(3)) 287 | 2 ([ * 4 - ]) 3 NB. (x[y)*(4-(x]y)) = 2*(4-(3)) 288 | 2 ( * 4 - ]) 3 NB. x*(4-( ]y)) = 2*(4-(3)) 289 | ( * 4 - ]) 3 NB. y*(4-( ]y)) = 3*(4-(3)) 290 | 291 | NB. As sequences of verbs that do not execute create trains there needs 292 | NB. to be a different way to factor out a simple pipeline of verbs! 293 | NB. Combine them with conjunction @: or @ 294 | <"0 - 1 2 3 NB. negate elements, then box each 295 | boxneg =: <"0 - NB. a train instead of the factored out pipeline 296 | boxneg 1 2 3 NB. ultimately a comparison: 1 2 3 <"0 - 1 2 3 297 | boxneg =: <"0 @: - NB. applies < after - 298 | boxneg 1 2 3 299 | (< @: -) 1 2 3 NB. show that u@:v applies u to whole result of v 300 | (< @ -) 1 2 3 NB. instead u@v applies u to each result of v 301 | NB. To write a pipeline monad after dyad simply apply the result of 302 | NB. conjunctions @: or @ dyadically: 303 | 1 2 (< @: -) 3 4 NB. applies monad to whole result of dyad 304 | 1 2 (< @ -) 3 4 NB. applies monad to every subresult of dyad 305 | NB. To apply a monad to each argument of a dyad conjunctions & or &: can 306 | NB. be used: 307 | ((<1),(<2)) (, &: >) ((<3),(<4)) NB. applies dyad to whole results 308 | ((<1),(<2)) (, & >) ((<3),(<4)) NB. applies to each subresult pair 309 | NB. Wouldn't it be awesome to put the result/s in the last example back 310 | NB. into a box? Use conjunctions &. and &.: to undo the first verb 311 | NB. afterwards: 312 | ((<1),(<2)) (, &.: >) ((<3),(<4)) NB. undoes the unboxing in the end 313 | ((<1),(<2)) (, &. >) ((<3),(<4)) NB. same but for each subresult 314 | NB. &. and &.: also works for monad after monad pipelines: 315 | (- &.: >) ((<1),(<2)) 316 | (- &. >) ((<1),(<2)) 317 | NB. To factor out a function with an argument use conjunction & 318 | 1 - 1 2 3 319 | oneminus =: 1 - NB. error 320 | oneminus =: 1 & - NB. creates a monad invoking dyad - with left arg 1 321 | oneminus 1 2 3 322 | minusone =: - 1 NB. executes expression (- 1) and saves its value 323 | minusone 324 | minusone =: - & 1 NB. creates a monad invoking dyad - with right arg 1 325 | minusone 1 2 3 326 | 327 | NB. The booleans (truth values) are simply the numbers 0 (false) and 1 328 | NB. (true). Arrays are equal if their shape and each atom match which 329 | NB. can be tested with dyad -: 330 | 1 > 0 1 2 NB. less than 331 | 1 < 0 1 2 NB. greater than 332 | 1 >: 0 1 2 NB. less or equal 333 | 1 <: 0 1 2 NB. greater or equal 334 | 1 = i.2 2 NB. equals 335 | 1 ~: i.2 2 NB. not equal 336 | (i.2 2) -: i.2 2 NB. equal in shape and each atom 337 | (i.4) -: i.2 2 338 | -. (i.2 2) -: i.2 2 NB. not 339 | 0 0 1 1 +. 0 1 0 1 NB. or 340 | 0 0 1 1 *. 0 1 0 1 NB. and 341 | 342 | NB. To apply a function repeatedly use conjunction ^: with the number of 343 | NB. repetitions as the right argument. Infinite repetitions stop as soon 344 | NB. as the result stops changing, 1 or 0 repetitions either apply the 345 | NB. verb or return the argument unchanged. A verb to compute the number 346 | NB. of repetitions can be supplied instead of a fixed number. 347 | +&1 ^:(10) 0 NB. applies +&1 ten times 348 | +&1 ^:(<&10) 5 NB. if 5 less than 10 applies +&1 once 349 | +&1 ^:(>&10) 5 NB. if 5 greater than 10 applies +&1 once 350 | +&1 ^:(<&10)^:(_) 0 NB. while less than ten applies +&1 351 | 352 | NB. Indices of arrays start at zero and may be negative to count from 353 | NB. the back. Every box in an index holds the path to a selection. To 354 | NB. select several elements on the same dimension group put them in 355 | NB. another box. Wrapping in a third box excludes the given indices; 356 | NB. excluding none selects all. 357 | i.10 10 358 | (<0) { i.10 10 NB. 1st element 359 | ((<0),(<_1)) { i.10 10 NB. 1st and last elements 360 | (<0 _1) { i.10 10 NB. 1st element then last 361 | (<(<0 1 2),(<_1)) { i.10 10 NB. 1st,2nd,3rd elements then last 362 | (<(<0 1 2),(<<_1)){ i.10 10 NB. 1st,2nd,3rd elements without last 363 | (<(<<''),(<_1)) { i.10 10 NB. all elements, then last 364 | 365 | NB. Replacing elements in arrays is like indexing but using adverb } and 366 | NB. specifying the replacements as left argument to the created verb. 367 | 1000 (<0) } i.10 10 NB. 1st element 368 | 1000 ((<0),(<_1)) } i.10 10 NB. 1st and last elements 369 | 1000 (<0 _1) } i.10 10 NB. 1st element then last 370 | 1000 (<(<0 1 2),(<_1)) } i.10 10 NB. 1st,2nd,3rd elements then last 371 | 1000 (<(<0 1 2),(<<_1))} i.10 10 NB. 1st,2nd,3rd elements without last 372 | 1000 (<(<<''),(<_1)) } i.10 10 NB. all elements, then last 373 | 374 | NB. Instead of a specific index a verb may be supplied, which is invoked 375 | NB. with the replacements as left and the array as right argument. This 376 | NB. verb must return the relevant indices of a flattened version of the 377 | NB. array, which allows to use it with arrays of any dimension! 378 | , i. 3 3 NB. monad , flattens an array 379 | 0 1 2 # 'abc' NB. dyad # copies elements in y x-times 380 | lower =: {{ 381 | flat =. , y 382 | len =. # flat 383 | indices =: i. len 384 | NB. only keep indices where condition is true: 385 | (flat < x) # indices 386 | }} 387 | 44 lower } i.10 10 388 | 4 lower } i.3 3 NB. works for this array just the same 389 | -------------------------------------------------------------------------------- /abort-hanging-session.md: -------------------------------------------------------------------------------- 1 | # Aborting a running sentence: 2 | 3 | To **break** is to abort the execution of a sentence, without killing 4 | the process. 5 | 6 | In jconsole and the web version hitting ctrl-c *while a sentence 7 | executes* sends the break signal. Hitting ctrl-c in jconsole while no 8 | sentence executes, terminates the process. 9 | 10 | To break from a different session, for example when the target session 11 | became unresponsive, the target session needs to have a so called 12 | breakfile in `jpath '~user/break'` (check whether one appears there when 13 | staring the session). 14 | 15 | If no breakfile exists, it can be created (obviously only before the 16 | session hangs) by running `setbreak 'foo'` in the relevant session, 17 | which tags the session as "foo". 18 | 19 | Then, abort the running sentence in this session by calling `break 20 | 'foo'` from another J session. By default JQt creates a breakfile 21 | "default" which can be triggered without having to name it (`break ''`). 22 | Jconsole sessions do not have a breakfile by default. 23 | 24 | In my experience it might be necessary to send the break signal 25 | repeatedly sometimes (regardless of whether ctrl-c or a break-file is 26 | used). 27 | -------------------------------------------------------------------------------- /cut.md: -------------------------------------------------------------------------------- 1 | # Conjunction `;.` with a right argument becomes an adverb: 2 | 3 | ## monadic adverb `;.0` (rank _) 4 | 5 | Apply verb to `y` with all axes reversed. 6 | ```J 7 | [ i.2 3 4 8 | [;.0 i.2 3 4 NB. reverses dimensions -> result shape unchanged 9 | |: i.2 3 4 NB. for comparison; reverses shape -> shape changes 10 | ``` 11 | 12 | ## dyadic adverb `;.0` (ranks 2 _) 13 | 14 | Apply verb to window at position and shape `x`. `x` is table with first 15 | line giving starting positions per axis, and second line giving number 16 | of elements to take. Thus `x` can be created `pos ,: shape`. 17 | ```J 18 | (1 2 ,: 3 4) ];.0 i.10 10 19 | ``` 20 | 21 | ## monadic adverbs `;.1`, `;._1`, `;.2` and `;._2` (all rank _) 22 | 23 | These adverbs apply their verb to each part of y which is delimited by 24 | occurrences of a certain element of `y`. The variants with 1 start each 25 | part with the first element of `y`, while the variants with 2 end each 26 | part with the last element of `y`. The negative variants remove the 27 | delimiting element before applying the verb. 28 | ```J 29 | < ;.1 '-ab-=cd=' 30 | < ;.2 '-ab-=cd=' 31 | < ;._1 '-ab-=cd=' 32 | < ;._2 '-ab-=cd=' 33 | ``` 34 | 35 | ## dyadic adverbs `;.1`, `;._1`, `;.2` and `;._2` (all rank 1 _) 36 | 37 | These adverbs are similar to their monadic variants but instead of using 38 | every occurrence of the first/last item as delimiter, the positions of 39 | the delimiters are given explicitly by boolean list `x`. To select per 40 | axis/dimension supply a boolean list for each as list of boxes; an empty 41 | element takes the whole dimension. 42 | ```J 43 | 0 1 0 1 0 <;.1 'a-b-a' NB. everything before first delimiter is missing 44 | 0 1 0 1 0 <;.2 'a-b-a' NB. everything after last delimiter is missing 45 | 0 1 0 1 0 <;._1 'a-b-a' NB. without demiliter 46 | 0 1 0 1 0 <;._2 'a-b-a' NB. without delimiter 47 | 48 | 0 1 0 0 0 <;.1 'a-b-a' NB. x is delimiters not this elem's occurrences 49 | 50 | NB. per line put delimiters on first and second elements 51 | (''; ''; 1 1 0 0 0) <;.1 i.3 4 5 52 | NB. + per table put delimiters on second and third line 53 | (''; 0 1 1 0; 1 1 0 0 0) <;.1 i.3 4 5 54 | NB. + per brick put delimiters on second table 55 | (0 1 0; 0 1 1 0; 1 1 0 0 0) <;.1 i.3 4 5 56 | ``` 57 | 58 | ## dyadic adverbs `;.3` and `;._3` (ranks 2 _) 59 | 60 | These create a moving window and apply their verb to its contents. The 61 | difference is that the negative variant stops moving the window in a 62 | direction if there are no more elements, while the positive variant 63 | keeps moving the window in a direction as long as it can see something. 64 | Therefore what the window of a negative variant sees always has the same 65 | shape. 66 | 67 | The first line in `x` specifies the movement of the window, but can be 68 | omitted, in which case the window moves by 1. (The second line in) `x` 69 | specifies how many elements to take per axis/dimension, which can also 70 | be thought of as the shape of the window for low dimensional data. 71 | 72 | ```J 73 | i.5 5 74 | 2 3 <;._3 i.5 5 NB. x of rank 1 interpreted as (1,:x) 75 | 2 3 <;.3 i.5 5 76 | 77 | i.3 4 5 78 | 2 3 <;._3 i.3 4 5 NB. unexpected result as it means: (2 3 _) 79 | 1 2 3 <;._3 i.3 4 5 NB. while this window shape was intended 80 | 81 | (1 2,:2 3) <;.3 i.5 5 NB. move by 2 on lines and by 1 on tables 82 | (2 1,:2 3) <;.3 i.5 5 83 | (2 2,:2 3) <;.3 i.5 5 84 | 85 | NB. non-overlapping views by setting movement to window's shape 86 | (,:~ 2 3) <;.3 i.5 5 87 | (,:~ 2 3) <;._3 i.5 5 88 | ``` 89 | 90 | ## monadic adverbs `;.3` and `;._3` (rank _) 91 | 92 | These are same as the dyadic versions but automatically compute the 93 | shape of the window: Each dimension is as long as the shortest dimension 94 | of `y` and the rank is the same as `y`. 95 | ```J 96 | <;._3 i.2 3 NB. 2 (lowest in shape of y) 2x (rank of y): (2 2) 97 | <;._3 i.2 3 4 NB. 3#2 gives a shape of (2 2 2) 98 | $;.3 i.2 3 4 NB. note: *rank* doesnt change; but shape does 99 | ``` 100 | -------------------------------------------------------------------------------- /iterating-over-locales.ijs: -------------------------------------------------------------------------------- 1 | NB. There is an article on the J wiki describing some complicated ways 2 | NB. of iterating over some locales: 3 | NB. 4 | NB. I would do it like this: 5 | 6 | NB. some class C 7 | coclass 'C' 8 | create =: {{ foo =: y }} 9 | destroy =: {{ codestroy '' }} 10 | get =: 3 : 'foo' 11 | set =: 4 : 'foo =: y' 12 | inc =: 3 : 'foo =: foo + 1' 13 | 14 | cocurrent 'base' 15 | 16 | NB. some instances 17 | o1 =: 100 conew 'C' 18 | o2 =: 200 conew 'C' 19 | o3 =: 300 conew 'C' 20 | 21 | NB. we want to avoid having to do this: 22 | get__o1 '' 23 | get__o2 '' 24 | get__o3 '' 25 | 26 | NB. iterating over a group of locales/instances 27 | group =: o1, o2, o3 28 | {{ 29 | for_o. group do. inc__o '' end. 30 | for_o. group do. echo get__o '' end. 31 | }} '' 32 | 33 | NB. cleanup 34 | {{for_o. group do. destroy__o '' end.}}'' 35 | conames '' 36 | coerase <'C' 37 | erase 'group o1 o2 o3' 38 | names '' 39 | -------------------------------------------------------------------------------- /understanding-j.md: -------------------------------------------------------------------------------- 1 | 2 | 21 | 22 | - J versions: 9.4.2, 23 | 24 | Found anything wrong? File an issue at 25 | . 26 | 27 | --- 28 | 29 | # Understanding J 30 | 31 | > An introduction to the J programming language that gets to the point. 32 | 33 | It is intended for those with (some) programming experience, but others 34 | should be mostly fine after looking up some basic programming terms like 35 | function, argument, class, instance, inheritance, statement, expression, 36 | etc. 37 | 38 | Don't treat this as a reference: Section titles do not introduce an 39 | exhaustive explanation of a certain topic, but serve to give this 40 | document a rough structure. Individual sections are not intended to be 41 | read in isolation from the others and assume the knowledge of previous 42 | sections. 43 | 44 | **Run the examples and read the comments!** 45 | 46 | If you have J installed you can open this file in JQt via the 47 | file-selection dialog which opens with `ctrl+o` (make sure to set the 48 | filetype-filter to "all"). Click on a line with J code and press 49 | `ctrl+enter` to execute it. 50 | 51 | Covered builtins are listed in the appendix with a short description. 52 | 53 | Important links: 54 | 55 | - Project Homepage: 56 | - Online J interpreter: 57 | 58 | - **All builtin operators**, with links to their wiki pages: 59 | 60 | - Good old wiki: 61 | 62 | - Cheatsheet/Reference Card (not for beginners): 63 | 64 | 65 | --- 66 | 67 | ## History: 68 | 69 | J was first released in 1990 as a successor to APL, an alternative 70 | mathematical notation that is computer-executable and works well with 71 | multi-dimensional array data. Most notably J switches from APL's custom 72 | symbol-set to ASCII only, calling most basic builtins by a single symbol 73 | or a symbol with appended dot or colon, and giving distinct meaning to 74 | single symbols that usually appear in pairs like various braces and 75 | quotes (`[]"{}` etc). 76 | 77 | ## Comments: 78 | 79 | ```J 80 | NB. comments the rest of the line (latin: nota bene). 81 | ``` 82 | 83 | ## Numbers: 84 | 85 | J has many number-notations; the most important are: 86 | ```J 87 | 3 NB. integer 88 | 3.14 NB. float 89 | _3 NB. negative numbers start with underscore 90 | _ NB. sole underscore is infinity: a number 91 | __ NB. negative infinity 92 | 12j34 NB. complex number (sometimes used as argument pair) 93 | 16bcoffee NB. base-16 number (must be lowercase) 94 | ``` 95 | 96 | ## Lists, Booleans: 97 | 98 | The notation is simple: just put elements next to each other. All 99 | elements must to have the same type but as an empty list has no elements 100 | it can be combined with any other list. True and false are represented 101 | simply by the two numbers `1` and `0`. See also: strings 102 | 103 | ```J 104 | 0 1 NB. the booleans (truth values) in a 2-element list 105 | 0 1 2 3 4 NB. due to context a list of numbers not booleans 106 | (0 1 2) (3 4) NB. error: can't implicitly join lists, see below 107 | ``` 108 | 109 | ## Strings: 110 | 111 | Strings are lists thus an empty string is commonly used as empty list 112 | notation. The default string type is called "literal" and is UTF-8 113 | encoded which means the first 128 ASCII characters work well with arrays 114 | as they are a single byte long. String literals are singlequoted, and 115 | only this character is special; it is escaped by doubling it. See also: 116 | string representation and unicode 117 | 118 | ```J 119 | '' NB. empty string is empty list 120 | 'this is a string. it''s always singlequoted' 121 | ``` 122 | 123 | ## Nouns: 124 | 125 | *Nouns* are data values such as the ones covered until now. *Boxes*, 126 | which will be covered later, are nouns too. Lists are actually just a 127 | basic case of *arrays* which can be thought of as nested lists. 128 | 129 | Classes and their instances aren't nouns: they cannot be referenced 130 | directly; but their name can be saved as a string. 131 | 132 | Functions aren't nouns either; but by putting them into a special kind 133 | of list, *gerunds*, they can effectively be made one (also covered 134 | below). 135 | 136 | ### Special data types: 137 | 138 | J comes with some specialized data types, which wont be covered here, 139 | but shall at least be mentioned: 140 | 141 | - **Symbols**: They are a specialized type of string, which is 142 | immutable, treated as a single element and has optimized performance 143 | with searching, sorting and comparison operations. However, only a 144 | few, often used ones should be created, as they are registered in a 145 | global table and cannot be removed from it anymore. More info at: 146 | 147 | 148 | - **Sparse arrays**: If a sizable array (for example a list; see: 149 | arrays) consists of mostly the same repeated value, its size can be 150 | reduced by only saving the values which are not this so called 151 | sparse-element. Contrary to regular arrays, sparse arrays are 152 | displayed as a table of index-value pairs of the non-sparse-elements 153 | and need to be queried explicitly for their sparse-element. 154 | Computations with them are envisioned as equivalent to regular arrays 155 | but this is not fully implemented (for example, sparse arrays cannot 156 | be boxed (see: boxes) and strings (which are arrays) cannot be 157 | sparse); the results are usually sparse arrays too, however, the 158 | sparse-element might differ! More info at: 159 | 160 | 161 | ## Functions: 162 | 163 | **Verbs** are functions that take nouns as their argument/s and return 164 | nouns. A verb has access to its left argument via the local variable `x` 165 | and to its right argument via the local variable `y`. If there are 166 | arguments on both sides of a function it is called dyadic (such verbs 167 | are *dyads*) otherwise the function is monadic (and such verbs are 168 | called *monads*; not related to the haskell term). 169 | ```J 170 | - NB. fn (here minus) without arg does not execute 171 | - 1 NB. monad (1 arg, but may be list) 172 | 1 - NB. error: monads take their arg from the right only 173 | 1 - 2 NB. dyad (2 args, may be lists) 174 | 175 | - 1 2 NB. monad with list argument 176 | 0 1 2 , 3 4 NB. the dyad , joins lists 177 | ``` 178 | Note that the monadic and dyadic case here are two distinct functions: 179 | negate-number and subtract. They share a name (the symbol `-`) and a 180 | definition: the function `-` is *ambivalent*. A function does not have 181 | to have both cases. 182 | 183 | **Modifiers** are functions used to pre-process a statement/expression; 184 | this means they run before the main evaluation step. Modifiers return a 185 | new function that has, additionally to its own arguments `x` and `y`, 186 | access to the original arguments as variables `u` (left, `m` may be used 187 | instead to indicate a noun) and `v` (right, use `n` instead to indicate 188 | a noun). The new function may return any entity, even more modifiers, 189 | which would also be processed before the first verb evaluates! 190 | 191 | ```J 192 | 1 + 2 + 3 NB. dyadic + is addition 193 | + 1 2 3j4 NB. monadic + gives the complex conjugates: 1 2 3j_4 194 | +/ 1 2 3 NB. 6 because: 1 + 2 + 3 is 6 195 | ``` 196 | 197 | The last example showed that `+/y` is not the same as `+y` but rather 198 | `y1 + y2 + y3 ...`. This is because `/` is an *adverb* (a modifier that 199 | takes one argument to the *left*): It creates a new function that 200 | inserts the original argument `+` between all elements of its own 201 | argument `1 2 3`. 202 | 203 | *Conjunctions* only differ insofar as they (meaning the original 204 | modifiers not the returned entities) take two arguments. For example `&` 205 | takes a dyad and a noun and creates a new verb which always uses the 206 | given noun as one of its arguments and the argument to the newly created 207 | monad as the other argument: 208 | ```J 209 | 2 ^ 3 NB. dyad ^ is power: "two to the three" 210 | 2&^ 0 1 2 3 NB. convert dyad ^ with left arg 2 to a monad 211 | ^&(2) 0 1 2 3 NB. convert dyad ^ with right arg 2 to a monad 212 | ``` 213 | 214 | ## Assignments: 215 | 216 | Assignments use the operators `=:` (global) and `=.` (function-local). 217 | They return their values, but the interpreter does not display them, so 218 | often monads `[` or `]`, which return their argument unchanged, are used 219 | as prefix. When assigning to multiple variables the return value is 220 | still the original argument. 221 | ```J 222 | foo =: 1 NB. return value of assignment not shown 223 | [ foo =: foo + 1 NB. global assignment 224 | ] foo =. foo + 1 NB. local assignment if in function otherwise global 225 | 226 | NB. btw the dyadic versions return either the left or the right arg: 227 | 0 [ 1 228 | 0 ] 1 229 | ``` 230 | 231 | It is possible to assign multiple values at the same time, but the value 232 | returned is the unchanged original argument. 233 | ```J 234 | 'foo bar' =: 'val' NB. names as space joined strings 235 | foo 236 | bar 237 | baz=:'foo bar'=:3 4 NB. multi assignment returns unchanged arg 238 | baz NB. thus baz received the original arg 239 | foo NB. but foo got first 240 | bar NB. and bar got second value 241 | 'foo bar' =: 1 2 3 NB. error: same number of names as elements required 242 | ``` 243 | 244 | See also: importing code 245 | 246 | ## Importing Code: 247 | 248 | To run the code from some file use one of these convenient verbs: 249 | 250 | - `load`: Runs the specified file or shortname (list available 251 | shortnames with `scripts''`). 252 | - `loadd`: Like `load` but displays the lines before executing them. 253 | - `require`: Like `load` but files that were already loaded won't be 254 | loaded again. 255 | 256 | As these verbs, like all functions, have their own scope, assignments in 257 | the loaded file/s which use `=.` but target the current global scope get 258 | captured by the loading function's scope and thus are not available 259 | afterwards! 260 | 261 | ## Defining Entities (Functions, Nouns) by Explicit-Definition: 262 | 263 | Explicit-definitions are created with the `:` conjunction which returns 264 | an entity of the type indicated by the integer to its *left*: 265 | 266 | - `0` for nouns, 267 | - `1` for adverbs, 268 | - `2` for conjunctions, 269 | - `3` for monadic (optionally ambivalent) verbs, 270 | - `4` for dyads. 271 | 272 | The entities' value is specified as the *right* argument and is a string 273 | for functions. A value of `0` always means to read in the following 274 | lines as a string - until the next line containing `)` as its only 275 | printable character. 276 | 277 | ```J 278 | NB. nouns 279 | 0 : 'string' NB. creates noun with value 'string' 280 | 1 + 0 : 100 NB. creates and uses noun 100 (the number) 281 | echo '>', (0 : 0), '<' NB. creates noun from next lines and uses it 282 | A Multiline string. 283 | Make sure to put a space between the left arg and : because otherwise it 284 | is parsed as one of the functions __: or _9: to 0: or 1: to 9: or _: 285 | that ignore their args and always return their (negative) digit/infinity 286 | ) 287 | 288 | NB. verbs 289 | 1 (4 : 'x + y') 2 290 | (3 : '-y') 1 291 | (3 :'3 :''1+y'' y') 1 NB. nested 292 | fn =: 3 : 0 NB. assign new (ambivalent) multiline verb 293 | echo 'First the body of a monad, then optionally the body of a dyad' 294 | echo 'separated by a line containing : as its only printable symbol' 295 | : 296 | echo 'Multiline explicit-defs cannot be nested but may contain' 297 | 3 :'echo''one-line explicit-defs or (multiline) DDs (see below)''' 0 298 | ) 299 | fn 1 300 | 1 fn 2 301 | 302 | NB. adverb representing number in percent ( ": formats arg as string) 303 | echo 0.01 (1 : '( ": u * 100), ''%'' ') 304 | percent =: 1 : 0 NB. same as a multiline definition 305 | (": m * 100), '%' NB. using m to indicate left arg is noun 306 | ) 307 | echo 0.7 percent 308 | 309 | NB. conjunction that swaps its arguments and the args of its result 310 | swap =: 2 : 'y v u x' 311 | 4 % 2 NB. division 312 | % 2 NB. 1 divided by y 313 | 4 % - 2 NB. 4 divided by negative 2 314 | 4 - % 2 NB. operators swapped: 4 minus a half 315 | 2 - % 4 NB. swap args too: 2 minus a quarter 316 | 4 % swap - 2 NB. equivalent but done by the conjunction swap 317 | ``` 318 | 319 | ## Index-Functions, Helpers: 320 | 321 | As demonstrated, explicit definitions specify the type to create as a 322 | number. This pattern of selecting functionality with a numeric index is 323 | sort of J's guilty pleasure. In most cases one would look up the 324 | functions in the docs and assign an alias to often used ones; in fact, J 325 | already comes with a set of aliases (and other helpers): list them with 326 | `names_z_''`. New users should definitely look over the docs for `!:` 327 | (foreign function index) and `o.` (circle functions) to see what's 328 | available: 329 | 330 | 331 | 332 | ## Direct Definitions: 333 | 334 | Direct definitions, *DD*s for short, are another way to write explicit 335 | definitions. They are wrapped in double-braces and assume their type 336 | from the argument-variable-names used: 337 | 338 | - If variables `v` or `n` are used, a *conjunction*, 339 | - otherwise, if `u` or `m` are used, an *adverb*, 340 | - otherwise, if `x` is used, a dyad or ambivalent *verb* is created. 341 | 342 | A type may also be forced by appending `)` and one of the letters 343 | `n`oun, `a`dverb, `c`onjunction, `m`onad or `d`yad to the opening 344 | braces. 345 | 346 | The following examples contain more info about DDs and should be 347 | compared carefully with their actual output! 348 | 349 | ```J 350 | ]fn =: {{123}} NB. monad; internally represented as explicit-def 351 | echo 1 2 3 , {{123}} '' 352 | ]fn =: {{x + y [ echo 'dyad because uses x' }} 353 | 1 fn 2 354 | 355 | {{'>',{{)nstring}},{{)n123}},'<'}} 'nested; one-line string definitions' 356 | 357 | {{ echo '---' 358 | echo 'untyped multiline DD' 359 | echo '* may start on opening line' 360 | echo '* may contain other mutliline DDs' 361 | {{ NB. such as this one 362 | echo '* closing line doesn''t have to start with }}' 363 | echo '* may continue on closing line' }} 'like here' 364 | }} '' 365 | 366 | {{)m NB. only comment allowed on typed opening line 367 | echo '---' 368 | echo 'typed multiline DD is like an untyped one except:' 369 | echo '* makes sure it is of a certain type' 370 | echo '* must not start on opening line (comments allowed)' 371 | y NB. last value is returned 372 | 373 | }} {{)n NB.(not a comment) except a multiline DD noun *may* do so. 374 | multiline DDs which define nouns: 375 | * must be typed 376 | * always produce a single list of characters (a string) 377 | * everything (incl whitespace and comment on opening line) becomes 378 | part of the string, except: 379 | }} , {{)n 380 | the opening line if it is empty (as in this case -> no empty line) 381 | * must put closing braces as first characters of line: 382 | }} thus this does not end the definition, but this does: 383 | }} , '< * as the < indicated: always end in a newline' 384 | ``` 385 | 386 | ## Arrays: 387 | 388 | There is no datatype "list", it is just a term to describe a 389 | 1-dimensional collection of values. 390 | 391 | Arrays can be thought of as nested lists, however _every_ value is 392 | an array -- even lists which are not nested and values which are not 393 | even lists (also called **scalars** or **atoms**). 394 | 395 | Arrays must only contain atoms of the same datatype and all lists on the 396 | same nesting-level (**dimension**/**axis**) must be of the same length! 397 | 398 | Therefore an array can be described by its datatype and **shape**, which 399 | is a list of the lengths of the lists on each nesting level. The length 400 | of the shape is called the **rank** (or dimensionality) of the array. 401 | 402 | An array which only consists of an atom which is not part of any list 403 | has an empty shape and thus rank 0 ("0-dimensional"). A list of one atom 404 | is a 1-dimensional array because the length of its shape (`1`) is 1; 405 | wrapping this list in another list _prepends_ another dimension of 406 | length 1 to the shape which is now `1 1` and thus rank 2. 407 | 408 | While an array which only consists of an atom which is not part of any 409 | list has an empty shape, an empty array, meaning one that does not 410 | contain any atoms, must have at least one `0` in its shape. An array of 411 | 2 lists of 0 atoms each differs due to its shape (`2 0`) from an array 412 | of 0 lists of 2 atoms each (shape `0 2`) despite both being empty 413 | arrays. 414 | 415 | The length of an array is the length of its highest dimension (leftmost 416 | number in the shape) and always 1 for atoms! 417 | 418 | ```J 419 | $ 0 NB. monad $ gives shape; scalars have an empty shape 420 | # $ 0 NB. and therefore rank 0; monad # gives arg's length 421 | $ 0 1 2 NB. shape 422 | # $ 0 1 2 NB. rank 423 | 2 1 $ 10 20 NB. dyad $ reshapes array; new: 2 lists of 1 element 424 | $ 2 1 $ 10 20 NB. shape 425 | 2 $ 10 20 30 NB. reshaping may drop elements 426 | 5 $ 100 200 NB. or repeat the elements as needed 427 | 'ten', 20 NB. error: incompatible types 428 | 10, 3.14 NB. ok: both are numbers 429 | 2 2 $ 'abc' NB. don't forget that strings are arrays too! 430 | 'a',LF,'b' NB. strings 'a' and 'b' combined with a newline 431 | NB. ^^ predefined variable containing newline, also useful: TAB,CR,CRLF 432 | ``` 433 | 434 | ## Boxes, Trees: 435 | 436 | The container-type box is useful to get around the restrictions of 437 | arrays: A boxed value always appears as scalar of type box; therefore 438 | any values, each in their own box, can be put into the same array! 439 | 440 | A box not containing another box may be called **leaf** when talking 441 | about **trees**, structures consisting of nested boxes. J comes with 442 | special functions to simplify working with trees, such as `{::` to index 443 | them (see: indexing). 444 | 445 | ```J 446 | <3 NB. monad < puts the value passed as arg into a box 447 | ><3 NB. monad > opens/unboxes the outer box of a value 448 | <'' NB. an empty box is just a boxed empty array 449 | a: NB. equivalent; called "ace", a noun 450 | 451 | 1 ; 3 NB. dyad ; joins args as boxes 452 | 1 ; <3 NB. it removes 1 boxing level from its right arg 453 | (<1); <3 NB. but not from its left arg; therefore 454 | (<1),<( (<2),<<3 ) NB. building trees with , helps seeing nesting level 455 | 456 | 1 2 , 'abc' NB. error: different types and lengths 457 | 1 2 ; 'abc' NB. ok because ; boxes the values first 458 | (<1 2) , <'abc' NB. here we manually boxed the values first -> ok 459 | 460 | NB. multi assignments unpack top-level boxes: 461 | ]'foo bar' =: 0 1;2 NB. removes one boxing level but returns original 462 | foo, bar 463 | 464 | NB. comparison of boxed values 465 | 'bar' = 'baz' 466 | (<'bar') = <'baz' 467 | (<'bar') = <'bar' 468 | 'bar' = <'bar' 469 | ``` 470 | 471 | ## (Explicit) Control-Structures and Control-Words: 472 | 473 | J has all common control-structures and -words, however, they can only 474 | be used within explicit functions (explicit definitions or DDs). They 475 | are not idiomatic J and hinder new users from learning to think in array 476 | programming style (see: idiomatic replacements for explicit 477 | control-structures). Nevertheless, some problems are simpler to solve 478 | this way. 479 | 480 | - Assert: *All atoms* have to be `1`. 481 | ```J 482 | {{ 483 | assert. 'aa'='aa' NB. dyad = compares corresponding atoms: 1 1 484 | assert. 'aa'='ab' NB. error because not all 1s: 1 0 485 | }}'' 486 | ``` 487 | - Conditionals: *First atom* must not be `0`. 488 | ```J 489 | {{ if. 0 1 do. NB. first atom is 0 -> false 490 | echo 'if block' 491 | elseif. 1 0 do. NB. first atom is not 0 -> true 492 | echo 'elseif block' 493 | elseif. 1 do. NB. only considered if no previous block ran 494 | echo 'elseif 2 block' 495 | else. NB. runs if no previous block ran 496 | echo 'else-block' 497 | end. }}'' 498 | 499 | NB. therefore be careful with tests such as: 500 | {{ if 'bar' = 'baz' do. echo 'true' else. echo 'false' end. }}'' 501 | ``` 502 | - Select: It first boxes unboxed arguments to `select.`, `fcase.` 503 | or`case.` then compares whether one of the boxes passed to `select.` 504 | is the same as a box passed to a `case.` or ` fcase.` statement and 505 | executes the respective block. An empty `case.` condition always 506 | matches. After the evaluation of a `case.` block execution jumps to 507 | `end.`, while after executing an `fcase.` (fallthrough) block the 508 | following `case.` or `fcase.` runs unconditionally. 509 | ```J 510 | match =: {{ 511 | select. y 512 | case. 'baz' do. echo 'does not match ''bar'' due to both being boxed' 513 | case. 'bar' do. echo 'after case. jumps to end.' 514 | case. 1 2 3 do. echo 'due to the boxing only matches the list 1 2 3' 515 | case. 1; 2; 3 do. echo 'box it yourself to get the desired cases' 516 | case. 4;5 do. echo 'one select.-box matching one f/case.-box suffices' 517 | fcase. 'fizz' do. echo 'after fcase. always executes next f/case.' 518 | fcase. 'buzz' do. echo 'fcase. stacks dont have to start at the top.' 519 | case. 'nomatch' do. echo 'no match but triggered by preceding fcase.' 520 | case. do. echo '... empty case. always matches' 521 | end. }} 522 | 523 | echo '---' 524 | match 'bar' 525 | match 1 2 3 526 | match 1 527 | match <2 NB. won't get boxed a second time 528 | match 4; 6 529 | match 4; 4 NB. despite several matches only runs block once 530 | match 'fizz' 531 | match 'buzz' 532 | match 'shouldn''t match but...' 533 | ``` 534 | - While loops: Only run if *first atom* is not `0`. 535 | ```J 536 | {{ 537 | foo =: 3 538 | while. 539 | (foo > 0), 0 NB. dyad > true if x greater than y 540 | do. 541 | echo foo =: foo -1 542 | end. 543 | }} '' 544 | ``` 545 | - Whilst loops: are while loops that always *run at least once*. 546 | ```J 547 | {{ whilst. 0 1 do. 548 | echo 'runs at least once' 549 | end. }} '' 550 | ``` 551 | - For (-each) loops: There are no classic for loops. Iterating over a 552 | list of integers can mimic one. If a for-loop does not terminate early 553 | its element-holding variable is set to an empty list and its 554 | index-holding variable to the length of the list. If it terminates 555 | early their last states are kept. 556 | ```J 557 | {{ 558 | for. 1 2 do. 559 | echo 'runs once per item. Neither item nor index are available...' 560 | end. 561 | }} '' 562 | 563 | fn =: {{ 564 | foo =: 'for_. hides global [_index]. with local versions' 565 | NB. see: namespaces for more info about local/global assignments 566 | foo_index =. 'for_. modifies local [_index]' 567 | for_foo. 'abc' do. 568 | echo foo; foo_index 569 | if. y do. 570 | early =. 'yes' 571 | break. 572 | else. 573 | early =. 'no' 574 | continue. NB. does not terminate loop just current iteration! 575 | end. 576 | echo 'never runs' 577 | end. 578 | echo 'terminated early?'; early; 'foo:'; foo; 'foo_index:';foo_index 579 | }} 580 | fn 1 581 | fn 0 582 | echo 'value of global foo:'; foo NB. unchanged 583 | ``` 584 | - Return statements: Exit function early. Pass a return-value as *left* 585 | argument! 586 | ```J 587 | {{ NB. functions return last computed value 588 | <'foo' 589 | <'bar' 590 | }} '' 591 | {{ 592 | <'foo' 593 | return. NB. exits early and returns last computed value 594 | <'bar' 595 | }} '' 596 | {{ 597 | <'foo' 598 | <'fizz' return. NB. or given left arg (parens not necessary??) 599 | <'bar' 600 | }}'' 601 | ``` 602 | - Goto: `goto_MYLABEL.` continues execution at the location marked: 603 | `label_MYLABEL.`. Consider that many (most prominently Dijkstra who 604 | advocated for structured programming) warn of goto's tendency obscure 605 | the flow of a program making it hard to maintain and debug. Goto's 606 | best usecase is probably to escape deeply nested loops, which 607 | are inherently un-idiomatic J code anyways (see: idiomatic 608 | replacements). 609 | - Error handling: see: Errors 610 | 611 | ## Errors: 612 | 613 | Verbs related to errors and debugging can be found in section 13 of 614 | the foreign function index (`13!: n`) but there are default aliases, 615 | which will be used below. 616 | 617 | Errors have a number and a message, which defaults to (err - 1)th 618 | element in the list of default error messages returned by `9!:8''`. 619 | `dberr` queries the last error's number and `dberm` gets its message. 620 | 621 | To raise an error its number is passed to `dbsig` which optionally 622 | accepts a custom error message as left argument. (Show the correct 623 | function name instead of "dbsig" in the message by using `(13!:8)` 624 | directly). 625 | 626 | ```J 627 | getinfo =: {{ 628 | echo 'An error occurred...' 629 | echo 'Its number is: ', ": dberr '' 630 | echo 'And its message is:', LF, ": dberm '' }} 631 | might_fail =: {{ 632 | if. y do. 633 | echo 'success' 634 | else. 635 | echo 'failure' 636 | 'my custom message' dbsig 100 NB. raise an error 637 | end. }} 638 | namedfn =: {{ 639 | try. 640 | might_fail y 641 | catch. getinfo'' 642 | end. 643 | echo 'after try-catch' }} 644 | 645 | namedfn 0 646 | ``` 647 | 648 | When J runs in debug mode, which can be en/disabled with a boolean 649 | argument to `dbr`, and queried with `dbq`, errors in *named* functions 650 | pause execution and messages contain a bit more information; the 651 | program state can then be investigated and altered. 652 | 653 | ```J 654 | dbr 1 NB. turn on debugging 655 | namedfn 0 NB. more info but does not pause because handled 656 | 657 | namedfn =: {{ 658 | try. might_fail y 659 | catchd. NB. pause on error 660 | echo 'adding catchd. clause pauses execution if debugging is on' 661 | echo 'catchd. block only executes if:' 662 | echo ' * debugging is off and' 663 | echo ' * there is no catch. block' 664 | catch. 665 | echo 'catch. block only executes if there is no catchd. block' 666 | getinfo'' 667 | end. 668 | echo 'after try-catch' }} 669 | namedfn 0 NB. pauses, does not run any catch./catchd. blocks 670 | dbs '' NB. inspect stack 671 | dbnxt '' NB. continue program 672 | 673 | NB. dbq'' does not inform about whether execution is currently paused 674 | NB. but only whether debug mode is on or not. currently it is: 675 | dbq '' 676 | 677 | dbr 0 NB. turn off debugging 678 | namedfn 0 NB. doesn't pause, runs catch. block 679 | 680 | namedfn =: {{ 681 | try. might_fail y 682 | catchd. echo 'not debugging and no catch thus catchd. block may run' 683 | end. 684 | echo 'after try-catch' }} 685 | namedfn 0 686 | ``` 687 | 688 | J has a `throw.` keyword which is equivalent to raising error 55 with 689 | `dbsig` and behaves differently from other errors: `throw.`ing 690 | immediately exits the current function and goes up the callstack until 691 | it finds a caller which used a `try.` block with a `catcht.` clause, 692 | which is then executed. If no `catcht.` is found an "uncaught throw." 693 | error is raised. 694 | 695 | ```J 696 | NB. normal errors look for catch./catchd. in same try. statement 697 | inner =: {{ 698 | try. dbsig 14 NB. no left arg -> default message 699 | catch. echo 'inner function''s catch. block' 700 | end. 701 | echo 'inner fn done' }} 702 | outer =: {{ 703 | try. inner '' 704 | catch. echo 'outer function''s catch. block' 705 | end. 706 | echo 'outer fn done' }} 707 | outer '' 708 | 709 | NB. throw. looks for catcht. in *caller* (or its callers) 710 | inner =: {{ 711 | try. 712 | echo 'throwing up...' 713 | throw. 714 | catch. echo 'inner function''s catch.' 715 | catcht. echo 'inner function''s catcht.' 716 | end. 717 | echo 'inner fn done' }} 718 | outer '' 719 | outer =: {{ 720 | try. inner'' 721 | catch. echo 'outer function''s catch. block' 722 | catcht. echo 'outer function''s catcht.' 723 | end. 724 | echo 'outer fn done' }} 725 | outer '' 726 | ``` 727 | 728 | ## Ranks and Frames: 729 | 730 | The **rank of a noun is the length of its shape**. Note that the shape 731 | of a scalar/atom is an empty list, thus a scalar's rank is 0; as well as 732 | that the number of elements on the lowest dimension (atoms) is the last 733 | number in the shape: 734 | 735 | ```J 736 | ] foo =: i.2 3 4 NB. monad i. creates number sequence in given shape 737 | $ foo NB. shape of foo 738 | #$foo NB. length of shape of foo; aka rank 739 | ]bar =: i.4 3 2 NB. has the reverse shape of foo 740 | ``` 741 | 742 | Every **verb defines a maximum allowed rank for its arguments**; this is 743 | called the "rank of a verb". As a verb may have a monadic and a dyadic 744 | version and a dyad has two arguments, "the" rank of a verb is actually a 745 | list of the three ranks in the following order: monadic, dyadic-left and 746 | dyadic-right rank. 747 | 748 | ```J 749 | ; b.0 NB. show ranks of ; which works on entire argument/s 750 | < b.0 NB. monad takes whole arg but dyad takes atoms only 751 | fn =: {{echo 'hi'}} NB. new verb 752 | fn b.0 NB. default ranks of new verbs are all infinity 753 | select 0-cells (atoms) 851 | <"_11 i.2 3 4 NB. abs val of neg rank higher than arg rank: 0-cells 852 | 853 | fn =: <"_1 NB. actually sets a negative rank... 854 | fn i.3 855 | fn i.3 3 856 | fn b.0 NB. ...but it is NOT SHOWN 857 | ``` 858 | 859 | Rank, even the default one, should always be considered as the 860 | application of a modifier -- and therefore as creating a new function 861 | which handles the invocation of the verb with the correct arguments. It 862 | is not simply a property of the verb that could be altered at will. 863 | Because of this, verb rank can never be increased: Every 864 | rank-conjunction can only work with the arguments it receives (possibly 865 | by a previous rank-operator) and therefore can only further constrain 866 | the rank. 867 | 868 | ```J 869 | ]tbl =: i.2 2 870 | < tbl NB. should be imagined as <"_ because rank is _ 0 0 871 | <"1 "2 tbl NB. "2 passes tables to "1 which calls < with lists 872 | <"2 "1 tbl NB. "1 passes lists to "2 which passes (them) to < 873 | 874 | NB. sequence of rank-conj is not the same as the minimum values: 875 | tbl ;"0 1 tbl NB. pair atoms with lines 876 | tbl ;"1 1 "0 2 tbl NB. for each atom-table pair: pair (atom) with line 877 | ``` 878 | 879 | ## Padding: 880 | 881 | Incompatible values can still be put into the same structure by using 882 | boxes. When they are of the same type, lower dimensional values can also 883 | be padded to match the shape of the higher dimensional value and thus 884 | the boxes can be omitted. This is different from reshaping! 885 | 886 | Unboxing automatically pads values. Behind the scenes this happens all 887 | the time when assembling subresults into a frame. 888 | 889 | ```J 890 | 1; 2 2 891 | >1; 2 2 NB. numeric arrays are padded with zeros 892 | 2 3 $ 'a' NB. reshaping reuses the original as needed 893 | >'a'; 'aaa' NB. padding adds filler if necessary. here spaces 894 | 895 | NB. note the resulting pattern: 896 | (2 1 $ 1); (2 3 $ 2) 897 | >(2 1 $ 1); (2 3 $ 2) 898 | (2 3 $ 1); (2 3 4 $ 2) 899 | >(2 3 $ 1); (2 3 4 $ 2) 900 | 901 | NB. different length results are padded before being put into a frame as 902 | NB. this example (that creates y by y matrices) shows: 903 | (3 : '1 + i.y,y' "0) 1 2 3 904 | ``` 905 | 906 | ## Evaluation Rules: 907 | 908 | After reading the previous sections the following rules should not be 909 | surprising: 910 | 911 | - Evaluation works right to left and in two steps: 912 | 913 | 1. Evaluate modifiers until only nouns and verbs are left, 914 | 2. then evaluate those. 915 | 916 | Right to left does not simply mean reading the words in reverse order 917 | but to find the rightmost verb or modifier (depending on current 918 | step), then determining its arguments and replacing all of that with 919 | its evaluation result. This repeats until the line is processed 920 | entirely. 921 | ```J 922 | - -/ 1 2 3 NB. 1. modifiers: find rightmost: / it's arg is - 923 | - 1 - 2 - 3 NB. 1a. result -fn 1 2 3 but expressed as its effect 924 | - 1 - _1 NB. 2. verbs: rightmost - has args 2 and 3 result _1 925 | - 2 NB. rightmost verb - has args 1 and _1 result 2 926 | _2 NB. rightmost verb - only has right arg: 2 result _2 927 | 928 | 0 1 + - 2 3 NB. this is (0 1 + (- 2 3)) 929 | ``` 930 | - No mathematical operator precedence, just right to left evaluation and 931 | parentheses. 932 | ```J 933 | 2 * 3 + 4 NB. 14 934 | (2 * 3) + 4 NB. 10 935 | ``` 936 | - Parentheses form subexpressions, that complete before the parent. 937 | ```J 938 | (3-2) - 1 NB. subexpr completes first and returns result: 1 939 | 940 | 1 (2) 3 NB. if this was not an error (2) were the number 2 941 | 1, (2), 3 NB. but it is a subexpr not a noun thus , is needed 942 | 943 | (- +) 1 2 3 NB. (-+) is not simply -+ but creates a (see:) train 944 | - + 1 2 3 NB. trains are not equivalent to unparentesized expr 945 | ``` 946 | - *Consecutive* modifiers are processed left to right: 947 | ```J 948 | 1 - ~ 3 NB. adverb ~ swaps the args of the verb it creates 949 | -~ 3 NB. or copies the right arg to the left 950 | 951 | join0 =: ,"0 NB. join atoms; technically already has a modifier " 952 | 'AB' join0 'CD' NB. but let's treat this as just some rank 0 verb 953 | 954 | 'AB' join0 ~ / 'CD' 955 | NB. first creates a function invoking join0 with swapped args 956 | NB. then combines each x- with each y-element using this new function 957 | 958 | 'AB' join0 / ~ 'CD' 959 | NB. first creates a function that combines each x- with each y-element 960 | NB. using dyad join0; then swaps the args to this new function 961 | ``` 962 | - Nouns are evaluated immediately, verbs only when called: 963 | ```J 964 | mynoun =: unknown + 1 NB. error; evaluates expr to get noun 965 | myverb =: 3 : 'unknown + 1' NB. ok because not yet evaluated 966 | myverb'' NB. error 967 | ``` 968 | 969 | ## Trains: 970 | 971 | ``` 972 | x? (E? D C B A) y 973 | result <---- D <---- B }combinators: dyads 974 | ? / \ except when their left arg is [: 975 | ? / \ 976 | E C A }operators: use train's arg/s, monads 977 | ? \ ? \ ? \ except when train not hook and has x 978 | x? y x? y x? y }using arguments of the train itself 979 | ------------- 980 | ======= \ 981 | last left arg All except the first operator may be replaced by: 982 | is missing in hooks *) [: which makes the combinator a monad 983 | then replaced with x or y *) noun to be used as left arg of combinator 984 | ``` 985 | 986 | An **isolated sequence of verbs (in other words: multiple verbs not 987 | followed by a noun) creates a train**, that is a special pattern 988 | defining which verbs receive what arguments and execute in which order. 989 | The basic idea is called **fork** and best explained by the computation 990 | of the arithmetic mean: 991 | ```J 992 | Y =: 1 2 3 4 993 | (+/ % #) Y NB. a list's mean is its sum divided by its length 994 | (+/ Y) % (# Y) NB. equivalent expanded form 995 | ``` 996 | 997 | A longer train simply continues this pattern using the result of the 998 | previous fork as the right argument to the next fork. When the last fork 999 | doesn't get a left argument (because the train is of even length) it 1000 | uses an argument of the train instead: its left, or if missing its right 1001 | one. This is called hook-rule and when it's used the whole train is 1002 | called *a* **hook**, otherwise its *a* fork. 1003 | ``` 1004 | Train: Expands to: Note: 1005 | ( C B A) y = ( C y) B ( A y) the basic fork 1006 | (E D C B A) y = ( E y) D (( C y) B ( A y)) just more forks 1007 | ( D C B A) y = y D (( C y) B ( A y)) last uses hook rule 1008 | ( B A) y = y B ( A y) just a hook 1009 | ``` 1010 | 1011 | Using my own terminology: A train consists of *operators* (the odd 1012 | numbered verbs counting from right) that *operate* on the train's 1013 | arguments, and *combinators* (the even numbered verbs counting from 1014 | right) that are dyads *combining* the result of everything to their 1015 | right with the result of the operator to their left. 1016 | 1017 | As said before, a hook's last combinator uses an argument of the train 1018 | to replace its missing left operator. When the train is dyadic, another 1019 | peculiarity of hooks becomes evident: A hook's operators are always 1020 | monads, ignoring the train's left argument: 1021 | ``` 1022 | x (E D C B A) y = (x E y) D ((x C y) B (x A y)) operators are dyads 1023 | x ( D C B A) y = x D (( C y) B ( A y)) operators are monads 1024 | x ( B A) y = x B ( A y) just a hook 1025 | ``` 1026 | 1027 | Any left operator may be replaced with a noun to create a so called 1028 | **NVV (noun-verb-verb) fork**, which simply uses this noun as its left 1029 | argument: 1030 | ``` 1031 | x (E D 1 B A) y = (x E y) D ( 1 B (x A y)) left arg to B is 1 1032 | x ( D 1 B A) y = x D ( 1 B ( A y)) left arg to B is 1 1033 | ``` 1034 | 1035 | Any left operator may be replaced with `[:` to create a so called 1036 | **capped fork** which converts its combinator into a monad: 1037 | ``` 1038 | x (E D [: B A) y = (x E y)D ( B (x A y)) fork ([:BA) -> monad 1039 | x ( D [: B A) y = x D ( B ( A y)) fork ([:BA) -> monad 1040 | ``` 1041 | 1042 | Experiment with some trains: 1043 | ```J 1044 | NB. a verb like ; but which always adds a boxing level before joining 1045 | 'X Y' =: (<<'X'),(<<'Y') 1046 | X ; Y 1047 | X {{ (swap args 1069 | hi 'bob' 1070 | ``` 1071 | 1072 | ## Gerunds: 1073 | 1074 | A gerund is a **list containing** (the boxed definitions of) **verbs**, 1075 | thus creates a noun from verb/s. It can be created with conjunction 1076 | `` ``` and applied in different ways with `` `:``. (see also: indexing) 1077 | ```J 1078 | + ` - NB. creates list of two verbs: + and - 1079 | - ` '' NB. this gerund only has one element: - 1080 | # +`- NB. length of the noun, which is a list of verbs 1081 | 1082 | gerund =: +/ ` % ` # 1083 | 1084 | NB. (m`:0) applies each verb in m separately 1085 | gerund`:(0) 1 2 3 4 NB. equivalent to: 1086 | >(+/1 2 3 4);(%1 2 3 4);(#1 2 3 4) 1087 | 1088 | NB. (m`:6) creates a train from the verbs in m 1089 | gerund`:(6) 1 2 3 4 1090 | (+/ % #) 1 2 3 4 NB. equivalent; (computes the average) 1091 | 1092 | gerund `:(3) 1 2 3 4 5 NB. used as cyclic gerund with monadic adverb / 1093 | 1 +/ 2 % 3 # 4 +/ 5 NB. equivalent, see: cyclic gerunds 1094 | ``` 1095 | 1096 | ### Cyclic Gerunds: 1097 | 1098 | Many modifiers which apply their verb multiple times may instead take a 1099 | list of verbs, from which to take one per needed application of a verb. 1100 | If there are too few verbs in the list, it is simply looped over again 1101 | as often as needed. 1102 | 1103 | ```J 1104 | +/ 1 2 3 4 5 NB. modifier / uses its verb multiple times 1105 | 1 + 2 + 3 + 4 + 5 NB. equivalent 1106 | gerund / 1 2 3 4 5 NB. uses the verbs from gerund sequentially instead 1107 | 1 +/ 2 % 3 # 4 +/ 5 NB. equivalent 1108 | 1109 | NB. The rank operator " applies its verb to each cell(-pair) 1110 | (-&1) "0 (1 2 3 4 5) 1111 | (+&1) "0 (1 2 3 4 5) 1112 | (-&1)`(+&1) "0 (1 2 3 4 5) 1113 | ``` 1114 | 1115 | ## Names: 1116 | 1117 | Variable-names may only contain 1118 | 1119 | - ASCII-letters (upper and lowercase), 1120 | - numbers (but not as first character) and 1121 | - underscores (except leading, trailing or double). 1122 | 1123 | ```J 1124 | valid_name1 =: 'only ascii' 1125 | VALID_NAME1 =: 'case sensitive, ' 1126 | VALID_NAME1, valid_name1 1127 | 1128 | _invalid =: 1 1129 | 2bad =: 2 1130 | err_ =: 3 1131 | ``` 1132 | 1133 | Unknown variables are assumed to be verbs because nouns are evaluated 1134 | immediately when defined, so their variable parts have to exist 1135 | beforehand. Verbs, however, are only evaluated when used, so unknown 1136 | parts at the time of definition are ok. This also allows functions to 1137 | reference themselves! 1138 | ```J 1139 | foo =: 10 1140 | ] bar =: 1 + foo NB. foo is noun, immediately evalueted: bar is 11 1141 | 1142 | foo =: unknown + 1 NB. error executing monad unknown 1143 | foo =: 1 + unknown NB. assumed verb without arg -> not evaluated -> ok 1144 | foo '' NB. error unknown not found 1145 | unknown =: 10 NB. now unknown exists but: 1146 | foo '' NB. error unknown not a verb 1147 | unknown =: 3 : '10' NB. now it is a verb (always returning 10) 1148 | foo '' NB. ok 1149 | 1150 | foo=:3 :'missing+1' NB. verb definition ok because not evaluated yet 1151 | foo '' NB. error missing not found 1152 | missing =: 10 1153 | foo '' NB. ok 1154 | 1155 | fn =: {{ 1156 | if. y > 0 do. 1157 | echo y 1158 | fn y-1 NB. calling own name -> recursion 1159 | end. 1160 | }} 1161 | fn 3 1162 | ``` 1163 | 1164 | Variables create subexpressions just like parentheses do; imagine they 1165 | expand to their parenthesized value: 1166 | ```J 1167 | N =: 2 1168 | 1 N 3 NB. error: implicit joins are not allowed 1169 | 1170 | - + 1 2 3 NB. how about creating an alias for this action? 1171 | action =: - + 1172 | action 1 2 3 NB. not the same result! it's a subexpression: 1173 | (- +) 1 2 3 NB. this subexpression creates a hook (train) 1174 | ``` 1175 | 1176 | Each name lives in a namespace also called a locale: 1177 | 1178 | ## Namespaces: 1179 | 1180 | Every function has its own local scope, that is an **unnamed 1181 | namespace** that cannot be inherited, thus a function defined within 1182 | another function does not have access to the outer function's namespace 1183 | (except using `u.` or `v.`; see: Applying modifiers to local variables). 1184 | ```J 1185 | var =. 'global' NB. outside function =. is equivalent to =: 1186 | fn1 =: {{ 1187 | var =. 'local' NB. in a function =. writes to its local namespace 1188 | fn2 =. {{ 1189 | echo var NB. uses global var as there is no local var in fn2 1190 | var2 =: '=: always writes to global scope' 1191 | }} 1192 | fn2 '' 1193 | echo var2 NB. finds var2 in global namespace 1194 | 1195 | var2 =. 'local hides global of same name' 1196 | echo var2 1197 | erase 'var2' NB. removes var2 from *its* scope (which is local) 1198 | echo var2 NB. global version available again 1199 | erase 'var2' NB. careful: removes var2 from *its* scope (global!) 1200 | }} 1201 | fn1 '' 1202 | echo var2 NB. show that it's really gone again 1203 | ``` 1204 | 1205 | Control-structures do *not* have their own namespaces. for_name-loops 1206 | always use the local scope to create/update the loop variables. 1207 | ```J 1208 | foo =: 'global' 1209 | {{ 1210 | foo_index =. 'local' 1211 | for_foo. 'abc' do. echo 'foo:'; foo; 'foo_index:'; foo_index end. 1212 | echo 'foo:'; foo; 'foo_index'; foo_index 1213 | }} '' 1214 | echo 'global foo:'; foo 1215 | ``` 1216 | 1217 | The second type of namespace is the **named namespace**/locale, of which 1218 | there may be many but at any time only one may be the **current/global 1219 | namespace**, which is inherited by any function('s local namespace) when 1220 | it is called. Inheriting means if a name is not found it is looked for 1221 | in the inherited namespace/s, which for new named namespaces is "z" 1222 | (where the standard helpers are defined) by default. 1223 | ```J 1224 | conl '' NB. shows available named namespaces 1225 | coname '' NB. shows currently used named namespace (=global) 1226 | cocurrent <'base' NB. switches global namespace to namespace "base" 1227 | nl '' NB. shows all names defined in global namespace 1228 | nl 3 NB. show defined names of type: 0 1 2 or 3 (verbs) 1229 | clear '' NB. rm all names from given namespace or "base" 1230 | nl '' 1231 | echo'hi world' NB. echo not defined -> where does it come from? 1232 | copath <'base' NB. shows list of namespaces "base" inherits: "z" 1233 | cocurrent <'z' NB. make "z" the current=global namespace 1234 | nl '' NB. contains echo; use names'' for pretty display 1235 | cocurrent 'base' NB. switch back 1236 | ``` 1237 | 1238 | The examples showed that to evaluate a name in another namespace this 1239 | needs to become the global namespace first, as well as that namespaces 1240 | are addressed with strings. However, there is a simpler way of writing 1241 | this (but behind the scenes it does the same): **Locatives** are names 1242 | that specify a namespace either by appending its name in underscores or 1243 | by appending two underscores and the name of a variable that contains 1244 | the (boxed) name. 1245 | 1246 | ```J 1247 | names_z_ '' NB. pretty print names defined in "z" 1248 | var =: <'z' 1249 | names__var '' NB. same 1250 | {{ for_ns. conl'' do. NB. iterate over available namespaces 1251 | echo coname__ns'' NB. locatives temporarily switch namespaces 1252 | end. }} '' 1253 | coname '' NB. back in original namespace 1254 | ``` 1255 | 1256 | Note that in the last 4 lines the global namespace only changed during 1257 | the evaluation of the locative in `echo coname__ns''` but not while 1258 | executing `echo` with the result of `coname__ns''`. Moreover, while 1259 | `echo` too is a verb from another namespace, it is inherited and thus 1260 | does not change the global namespace! To use a locative-accessed verb 1261 | with the current global namespace use adverb `f.` to pull the verb into 1262 | the current namespace before executing it: 1263 | 1264 | ```J 1265 | fn_z_ =: fn =: {{ echo var }} 1266 | 1267 | var_z_ =: 'during locative' 1268 | var =: 'during orig namespace' 1269 | 1270 | fn 'executes fn from current namespace' 1271 | erase 'fn' 1272 | fn 'executes fn from inheritance' 1273 | fn_z_ 'executes fn from locative' 1274 | fn_z_ f. 'executes result of adverb (which gets fn from locative)' 1275 | ``` 1276 | 1277 | Namespaces are automatically created when used. 1278 | ```J 1279 | conl'' 1280 | ns =: <'mynamespace' 1281 | echo__ns 'inherited echo from "z", the default parent' 1282 | copath ns NB. show "mynamespace" inherits from "z" 1283 | ``` 1284 | 1285 | ## Applying modifiers to local variables: 1286 | 1287 | Function-namespaces not being inheritable becomes a problem when 1288 | applying modifiers to local variables: 1289 | 1290 | During evaluation phase 1 (see: Evaluation Rules) modifiers produce 1291 | verbs with identical body but `u` and `v` replaced with the operands of 1292 | the modifier, which were not yet evaluated. Then, during phase 2, the 1293 | verb encounters the unresolved name, tries to look it up and does not 1294 | find it since it does not have access to the caller's namespace. 1295 | 1296 | If a modifier uses `u.`/`v.` instead of `u`/`v` the resulting verb 1297 | starts the lookup of a name they stand for from the scope of its caller! 1298 | Here is an example: 1299 | ```J 1300 | F =: {{ 1301 | L =. + 1302 | L adv y NB. local var L stays unevaluated during phase 1 1303 | }} 1304 | 1305 | adv =: 1 : 'u/y' 1306 | F 1 2 3 NB. error: unknown var: L 1307 | 1308 | adv =: 1 : 'u./y' NB. looks for name L from the scope of the caller F 1309 | F 1 2 3 NB. ok 1310 | ``` 1311 | 1312 | ## Classes, OOP: 1313 | 1314 | In J, classes are simply namespaces whose instances (also namespaces) 1315 | inherit them. As assigning to inherited names just creates an own 1316 | version of the name in the inheriting namespace, shared fields need to 1317 | be accessed with a locative. 1318 | 1319 | By convention `conew` is used to create new instances: It calls 1320 | `cocreate` with an empty argument resulting in a new namespace with a 1321 | stringified, previously unused, numeric name and then prepends the 1322 | class' namespace to the list of ancestors. Finally `conew` remembers the 1323 | namespace from which the new instance was created as the variable 1324 | `COCREATOR`. Another convenience of the `conew` verb is that its dyadic 1325 | version also calls the monad `create` with its left arguments. By 1326 | convention a destructor should be implemented as the monadic function 1327 | `destroy` calling `codestroy` which simply uses `coerase` on the current 1328 | namespace. 1329 | 1330 | ```J 1331 | coclass 'C' NB. coclass is just an alias for cocreate 1332 | field =: 100 1333 | 1334 | create =: {{ 1335 | echo 'hi from C''s constructor' 1336 | field =: y 1337 | }} 1338 | destroy =: {{ 1339 | echo 'hi from C''s destructor' 1340 | codestroy'' 1341 | }} 1342 | 1343 | get =: 3 : 'field' 1344 | inc =: 3 : 'field =: field +1' 1345 | dec =: 3 : 'field =: field -1' 1346 | ``` 1347 | 1348 | ```J 1349 | cocurrent 'base' 1350 | c1 =: conew 'C' NB. wont call constructor 1351 | c2 =: 1 conew 'C' NB. calls constructor with its left args 1352 | echo (get__c1''); get__c2'' 1353 | dec__c1'' 1354 | inc__c2'' 1355 | echo (get__c1''); get__c2'' 1356 | ``` 1357 | 1358 | This demonstrates creating a class inheriting from another, as well as 1359 | how to use class-variables (as opposed to instance-variables), by 1360 | creating a singleton, that is, a class that at any time may only have 1361 | one instance: 1362 | ```J 1363 | coclass 'Singleton' 1364 | NB. inherit from "C": 1365 | NB. ('C'; (copath cocurrent'')) copath cocurrent'' 1366 | NB. or simply: 1367 | coinsert 'C' 1368 | 1369 | NB. Shall be used as class-variable (=shared by instances) 1370 | hasInstance =: 0 1371 | 1372 | NB. IMPORTANT: 1373 | NB. * Avoid using knowledge about internals of parents. Stick to 1374 | NB. their functions as much as possible! 1375 | NB. * Avoid recursion when overriding functions by using a locative. 1376 | NB. * Avoid executing the locative in parent by using the f. adverb! 1377 | 1378 | create =: {{ 1379 | echo 'hi from Singleton''s constructor' 1380 | echo 'Singleton''s parents are: ', ": copath 'Singleton' 1381 | if. hasInstance_Singleton_ do. 1382 | throw. 'Cannot create more than 1 instance of a singleton.' 1383 | end. 1384 | 1385 | create_C_ f. y 1386 | 1387 | NB. If "C"'s constructor throws, this does not run. 1388 | NB. Use locative to write to class-var not instance-var: 1389 | hasInstance_Singleton_ =: 1 1390 | }} 1391 | 1392 | NB. This shows why the destory function should always be implemented 1393 | NB. and used to dispose of instances: Some classes are intended to 1394 | NB. execute specific destruction behaviour but coerase does not call 1395 | NB. any destructors. Singleton breaks if hasInstance isn't reset: 1396 | destroy =: {{ 1397 | echo 'hi from Singleton''s destructor' 1398 | hasInstance_Singleton_ =: 0 1399 | 1400 | destroy_C_ f. '' 1401 | }} 1402 | ``` 1403 | 1404 | ```J 1405 | cocurrent 'base' 1406 | NB. show "Singleton"'s ancestors/parents (namespaces it inherits): 1407 | copath 'Singleton' 1408 | 1409 | s1 =: 111 conew 'Singleton' 1410 | get__s1 '' 1411 | 1412 | {{ try. 1413 | s2 =: 222 conew 'Singleton' 1414 | catcht. 1415 | echo 'Caught SingletonException: Already has an instance!' 1416 | end. }}'' 1417 | 1418 | destroy__s1 '' 1419 | s2 =: 333 conew 'Singleton' 1420 | get__s2 '' 1421 | 1422 | NB. clean up: 1423 | {{ 1424 | for_insta. s2; c1;c2 do. destroy__insta'' end. 1425 | coerase 'Singleton' 1426 | coerase 'C' 1427 | for_name. 's1';'s2'; 'c1';'c2' do. erase name end. 1428 | }}'' 1429 | ``` 1430 | 1431 | ## Indexing: 1432 | 1433 | How indices work in J: 1434 | 1435 | - The first element has index `0`. 1436 | - Negative indices select from the back (thus the last element can be 1437 | accessed with index `_1`). 1438 | - Each element in an index is a separate selection (of what differs per 1439 | verb). 1440 | - An *unboxed list* of indices selects (multiple of) the array's 1441 | top-level elements, because each element is a separate selection and 1442 | - *trailing* axes/dimensions may be omitted, resulting in all their 1443 | elements being selected. 1444 | - Top-level boxes (**1st boxing level**) contain paths, that is lists of 1445 | *selections per axis/dimension* of an array. In other words: Each 1446 | element in a box selects on a different axis/dimension of the array, 1447 | which effectively means they subindex the previous result. 1448 | - To select several elements on the same axis/dimension group them in 1449 | another box (**2nd boxing level**). 1450 | - *Instead*, elements can be excluded per axis/dimension by wrapping 1451 | them with another two boxes (**3rd boxing level**). 1452 | - To select all elements of an axis/dimension exclude none by putting an 1453 | empty array at the third boxing level (`<<<''` or `< first col 1465 | _1 { a NB. count from back 1466 | 0 0 { a NB. separate selections starting at same level 1467 | (<0 0) { a NB. top-level boxes contain paths 1468 | (1 1; 2 2) { a NB. separate selections with paths 1469 | (1; 1 1) { a NB. different length results need padding 1470 | (<(<0),(<1 3)) { a NB. select multiple elements per axis in path 1471 | (<( orig ; copy NB. show that copy is indeed unchanged 1485 | ``` 1486 | 1487 | To be able to write index getters that work for any array `}` accepts a 1488 | dyad as left argument: It takes the replacement/s as left and the 1489 | original array as right argument and returns the indices *of a flattened 1490 | version of the array* at which to replace values. 1491 | ```J 1492 | _ (1) } i.2 3 NB. noun-indices access the unflattened array 1493 | _ 1: } i. 2 3 NB. indices from functions are for flattened arrays 1494 | 1495 | 1 0 2 # 'abc' NB. dyad # copies corresponding element in y x-times 1496 | , i.2 2 NB. monad , flattens an array 1497 | fn =. 4 : 0 1498 | Y =. , y NB. flattened y 1499 | bitmask =. x>Y NB. where replacement greather than element... 1500 | bitmask # i. #Y NB. ...keep, else drop index from flat-indices list 1501 | ) 1502 | 0 fn } 2 6 $ foo =: _4 2 9 3 8 5 _7 _2 3 1 _3 2 1503 | 0 fn } 2 2 3 $ foo 1504 | ``` 1505 | 1506 | **Ranges** can be conveniently specified with (combinations of) the 1507 | following verbs: 1508 | ```J 1509 | ] digits =: i.10 1510 | {: digits NB. last (no dyadic version) 1511 | {. digits NB. first 1512 | 3 {. digits NB. first 3 1513 | _3 {. digits NB. last 3 1514 | 2 1 {. 3 3 $ digits NB. first 1 of first 2 1515 | }: digits NB. drop last (no dyadic version) 1516 | }. digits NB. drop first 1517 | 3 }. digits NB. drop first 3 1518 | _3 }. digits NB. drop last 3 1519 | 1 2 }. 3 3 $ digits NB. drop first 1 then first 2 (reshaping dropped 9) 1520 | 1521 | 3}. 7{. digits NB. range from (incl) 3 to (excl) 7 1522 | ``` 1523 | 1524 | ### Indexing Boxes: 1525 | 1526 | `{::` is like `{` but *opens its results* and uses *each path to 1527 | continue indexing into the previous result* instead of returning to the 1528 | starting level and producing more result values. The final *result is 1529 | not opened if* it is not a single box or the *last path's last part is a 1530 | list* (monad `,` can be used to promote a scalar to rank 1). `{::` only 1531 | works with paths because it will wrap lists of numbers in a box first. 1532 | ```J 1533 | ]a =: 1 2 3; 4 5 6; 7 8 9 1534 | (1;1) { a NB. paths start at same level 1535 | (1;1) {:: a NB. paths continue indexing previous result 1536 | ]a =: <<"0 i.3 3 1537 | (0;1 1) {:: a NB. final scalar box result is opened, except: 1538 | (0;(<1;,1)) {:: a NB. last path's last part is a list due to ,y 1539 | (0; 1) {:: a NB. not opened because result isn't a scalar box 1540 | (0; (<(<<1))) {:: a NB. excluding stuff etc works as it would with { 1541 | ``` 1542 | 1543 | ### Indexing Gerunds: 1544 | 1545 | As gerunds (see: gerunds) are simply lists of boxed verb-definitions, 1546 | they could be indexed like any other list; however, this would not 1547 | return an executable verb! Conjunction `@.` takes an index as right 1548 | argument and returns the corresponding verb from the gerund on the left 1549 | in executable form. Selecting multiple verbs returns a train (see: 1550 | trains) and parentheses can be set by boxing the indices accordingly. 1551 | (See also: conditional application) 1552 | ```J 1553 | gerund =: +/ ` % ` # ` - 1554 | div =: gerund @. 1 1555 | div 1556 | 1 div 2 1557 | from_mean =: gerund @. (< _1 ; 0 1 2) 1558 | from_mean 1559 | from_mean 1 2 3 4 1560 | ``` 1561 | 1562 | ## Idiomatic Replacements for Explicit Control-Structures: 1563 | 1564 | The control-structures described above (see: explicit control-structures 1565 | and control-words) can be replaced with more idiomatic versions which 1566 | also work outside of explicit functions. 1567 | 1568 | Note: Experimenting with the code in this section can easily result in 1569 | non-terminating ("infinite") loops! To abort them either kill the 1570 | process, which looses the session data, or call `break''` in another J 1571 | session. When running J from the terminal you can hit ctrl-c to break. 1572 | 1573 | ### Repeated Application: 1574 | 1575 | To apply a verb a certain amount of times (each time on the previous 1576 | result), either dyadically apply the result of creating a monad from a 1577 | dyad with `&` or use conjunction `^:`: 1578 | ```J 1579 | arg =: 100 1580 | < < < arg NB. "applying a verb (here <) 3x" 1581 | 3 -&1 arg NB. apply resulting monad 3x 1582 | -&1 ^:3 arg NB. apply given monad 3x 1583 | -&1 ^:1 arg NB. apply 1x 1584 | -&1 ^:0 arg NB. applying 0x returns arg unchanged 1585 | 1586 | NB. dyadic application of ^: first creates a monad! 1587 | 'x' ,^:3 'y' NB. bind left arg of dyad (here 'x'&,) then apply 3x 1588 | ``` 1589 | 1590 | Conjunction `^:` may take a verb instead of an explicit amount of 1591 | repetitions, which is called with the argument/s of the construct. Note: 1592 | A left argument is first bound to the repeating verb to create a monad! 1593 | ```J 1594 | printer =: {{ echo 'printing ticket for 1 ', >x }} 1595 | make_tickets =: printer ^: {{ 1596 | if. x = <'child' do. 1597 | +/ 18 > y 1598 | else. +/ y > 17 1599 | end. 1600 | }} 1601 | ages =: 36 42 9 13 71 1602 | (<'child') make_tickets ages NB. calls (<'child')&printer repeatedly 1603 | (<'adult') make_tickets ages NB. calls (<'adult')&printer repeatedly 1604 | ``` 1605 | 1606 | Run a verb **until its result stops changing** (that is consecutive 1607 | iterations return the same result) by using infinity as repetition 1608 | count: 1609 | ```J 1610 | dec_bottom0 =: {{ 1611 | if. 0 > new =. y-x do. 1612 | 0 [ echo 'subresult: ', ": 0 1613 | else. new [ echo 'subresult: ', ": new 1614 | end. 1615 | }} "0 1616 | 1617 | 1&dec_bottom0 ^:(_) 5 1618 | _ (1&dec_bottom0) 5 1619 | NB. - ^:(_) 5 NB. wont terminate: consecutive results never same 1620 | ``` 1621 | 1622 | Running the **same loop different amounts of times** is simply done by 1623 | providing a list of repetition counts. This can be used to return 1624 | subresults (which are not boxed!): 1625 | ```J 1626 | 3 (-&1) arg NB. 3x ... 1627 | 1 2 3 (-&1) arg NB. ... with subresults 1628 | -&1 ^:(1 2 3) arg NB. same 1629 | 1630 | NB. not same, despite result: 1631 | (-&1 ^:1 arg), (-&1 ^:2 arg), (-&1 ^:3 arg) 1632 | 1633 | NB. to better illustrate why it is not the same: 1634 | (1&dec_bottom0 ^:(1) 5),(1&dec_bottom0 ^:(2) 5),(1&dec_bottom0 ^:(3) 5) 1635 | 1&dec_bottom0 ^:(1 2 3) 5 1636 | ``` 1637 | 1638 | Providing the repetition count as a box is a recognized pattern to 1639 | **capture the subresults**. A box is interpreted as `i.>n`-repetitions 1640 | (except when the boxed value is empty or infinity, which both create an 1641 | infinite loop). Therefore, the construct only loops up to n-1 times and 1642 | includes the original argument as first result! Consequently subresults 1643 | must have the same type as the original argument. 1644 | ```J 1645 | 3 (-&1) arg NB. 3x ... 1646 | 1 2 3 (-&1) arg NB. ... with subresults 1647 | (<3) -&1 arg NB. ... interpreted as 0 1 2 (=i.3) repetitions 1648 | -&1 ^:(<3) arg NB. equivalent 1649 | 1650 | 1&dec_bottom0 ^:(<_) 5 1651 | a: (1&dec_bottom0) 5 1652 | ``` 1653 | 1654 | ### Conditional Application: 1655 | 1656 | A **simple conditional** either executes a branch or doesn't. In other 1657 | words: a verb is executed `1` or `0` times. Replacing the number of 1658 | repetitions with a boolean-expression is enough to create a conditional 1659 | because J's booleans are simply the numbers `0` and `1`: 1660 | ```J 1661 | NB. children (<18) only pay 75% 1662 | price =: 15 1663 | ages =: 36 42 9 13 71 1664 | (18 > ages) 0.75&* price NB. bool_expr bound_arg_action arg 1665 | *&0.75 ^:(18 > ages) price NB. action ^: bool_expr arg 1666 | ``` 1667 | 1668 | **Multiple branches** can be expressed with a gerund and passed as left 1669 | argument to conjunction `@.` (see: indexing gerunds), which calls the 1670 | selected branch with the given argument/s. The noun index as right 1671 | argument to `@.` may be replaced by a verb to generate it; this is also 1672 | called with the argument/s to the construct: 1673 | 1674 | ```J 1675 | NB. note that it's important whether the verbs are monads or dyads: 1676 | {{price}} ` {{price*0.75}} @. (18>]) "0 ages NB. noun indexing 1677 | {{price}} ` {{price*0.75}} @. {{18>y}} "0 ages NB. called as monads 1678 | price [ ` {{x*0.75}} @. (4 :'18>y') "0 ages NB. called as dyads 1679 | ages ] ` (4 :'y*0.75') @. {{18 > x}} "0 price NB. swapped args 1680 | 1681 | NB. more branches: ages >70 pay 70%, <18 pay 50% NB. adding booleans: 1682 | price {{x*0.5}} ` [ ` {{x*0.7}} @. (4 :'(>&70 + >&17) y') "0 ages 1683 | ``` 1684 | 1685 | ### Conditional Repetition: 1686 | 1687 | To create **while-loops** an infinite loop can be combined with a 1688 | conditional: once the condition fails its argument is returned 1689 | unchanged, thus reused in the next iteration and again returned which 1690 | then ends the loop, due to consecutive non-unique results. 1691 | 1692 | ```J 1693 | 1&dec_bottom0 ^:(>&3)^:(_) 8 1694 | 1&dec_bottom0 ^:(>&3)^:(a:) 8 1695 | 1696 | NB. using a multi branch conditional: 1697 | {{ y[ echo 'done'}} ` {{ res[ echo res=. y-1}} @. (>&3) ^:(a:) 8 1698 | 1699 | NB. here the condition is never true -> returns unchanged arg 1700 | 1&dec_bottom0 _1 NB. but here it's never even called: 1701 | 1&dec_bottom0 ^:(>&3)^:(a:) _1 1702 | ``` 1703 | 1704 | ### Looping with More Control: 1705 | 1706 | The 6 conjunctions `F.`, `F:`, `F..`, `F.:`, `F:.` and `F::` are 1707 | collectively known as Fold. Usage: `x? u Fold v y` 1708 | 1709 | Fold creates a **loop which invokes `v` on the previous result** of `v` 1710 | and **then allows to postprocess (even discarding) the result** with 1711 | `u`. However, the result of `u` is never the input to `v`. 1712 | 1713 | If the first inflection (appended "." or ":") of Fold is "." only the 1714 | last result is kept, while ":" combines the subresults into a final 1715 | result (which pads subresults if necessary and thus the last result 1716 | might differ from a Fold with a single result). 1717 | 1718 | `F.` and `F:` create an infinite loop which has to be exited explicitly. 1719 | They always provide `x` (if given) unchanged as left argument to `v` and 1720 | use `y` as a whole as initial right argument. 1721 | 1722 | Dyad `Z:`, which may be used in `u` and `v`, provides control over 1723 | Fold-created loops, similar to `break.` and `continue.` in explicit 1724 | loops. Its effect is determined by its left argument and only activated 1725 | if the right argument is not `0`: 1726 | 1727 | - `_3`: Raise "fold limit"-error (thus no result) if loop already ran 1728 | given (as right argument) number of times. Note that `_1 Z: 1` in `v` 1729 | does not increment the iteration count and thus might create an 1730 | infinite loop which is not caught by `_3 Z: n`... 1731 | - `_2`: Immediately exit the loop. `u` never runs or completes, thus 1732 | this iteration does not contribute to the overall result. Raises 1733 | "domain error" if overall result is empty. 1734 | - `_1`: Immediately exit current function and start the next iteration 1735 | with the result of `v` if in `u` or the previous result of `v` if in 1736 | `v`. `u` never runs or completes, thus overall result stays unchanged. 1737 | Note the danger of using this in `v` of `F.` or `F:` (see: above). 1738 | - `0`: Current iteration is not aborted, but the result of `u` is 1739 | discarded. 1740 | - `1`: Exit after finishing current iteration. 1741 | 1742 | ```J 1743 | double =: *&2 1744 | 1745 | NB. raises error in 5th iteration 1746 | NB. F: and F. as dyads always use original x argument 1747 | res =: 2 {{ y [_3 Z: 5 }} F: {{ x+y [echo x;y }} 0 1748 | res 1749 | 1750 | NB. stop once results are greater than 20 1751 | NB. F: and F. as monads apply v monadically, contrary to the other Folds 1752 | res =: {{ y [_2 Z: (y > 20) }} F: {{ ([ echo) double y }} 1 1753 | res 1754 | NB. Fold-Single only keeps last result 1755 | res =: {{ y [_2 Z: (y > 20) }} F. {{ ([ echo) double y }} 1 1756 | res 1757 | 1758 | NB. discard result if it is 8; regardless, it is used as previous value 1759 | {{ y [echo'afterwards';y [_2 Z:(y>20) [_1 Z:(y=8) }} F: {{double y}} 1 1760 | NB. In contrast (0&Z:) doesn't abort current iteration, only discards 1761 | NB. current result: 1762 | {{ y [echo'afterwards';y [_2 Z:(y>20) [ 0 Z:(y=8) }} F: {{double y}} 1 1763 | 1764 | NB. do not use (_1 Z: 1) in v when using F. or F: as it creates an 1765 | NB. infinite loop which is not caught by (_3 Z: n) 1766 | NB. {{ y [_3 Z: 10}} F: {{ new [_1 Z: (new=8) [echo new=: double y}} 1 1767 | 1768 | NB. finish current iteration and exit loop 1769 | {{ y [echo'afterwards';y [ 1 Z:(y=8) }} F: {{double y}} 1 1770 | ``` 1771 | 1772 | The other fold variants use `x`, if given, as initial right argument to 1773 | `v` and one item of `y` per iteration as left argument. The items of `y` 1774 | are used in order if the second inflection is "." and in reverse if it 1775 | is ":". If `x` is not given, the first/last item of `y` is used as 1776 | initial right argument and the second/-to-last item is the first left 1777 | argument to `v`. 1778 | 1779 | ```J 1780 | ]Y =: 1+i.5 1781 | ]F:., Y NB. forward order, not postprocessed, needs padding 1782 | 1850 | fn =: > NB. tacit function -> J guesses inverse 1851 | fn b._1 1852 | fn^:(_3) 'hi' NB. call inverse of fn 3 times 1853 | 1854 | NB. explicit function -> no automatic inverse generated 1855 | fn =: {{ 1856 | y+y 1857 | : 1858 | x+y 1859 | }} 1860 | fn b._1 NB. error: no inverse 1861 | 1862 | NB. assigning an inverse 1863 | fn =: fn f. :. {{ 1864 | y%2 1865 | : 1866 | x-y 1867 | }} 1868 | fn b._1 NB. the shown inverse is the whole definition 1869 | NB. testing the verb 1870 | fn 1 NB. monad 1871 | fn^:(_1) fn 1 NB. inverse of monad 1872 | 2 fn 3 NB. dyad 1873 | 5 fn^:(_1) 2 NB. inverse of dyad 1874 | 5 fn^:(_1) 3 1875 | 1876 | NB. let J generate tacit verb so it guesses inverse too 1877 | ]fn =: 13 : 'y^y' 1878 | fn b._1 NB. I didn't know that... 1879 | fn 3 1880 | fn^:(_1) fn 3 1881 | ``` 1882 | 1883 | ## Tacit replacements for constant functions: 1884 | 1885 | Functions returning the same value no matter their argument/s are called 1886 | constant. Nice tacit constant functions for the ten digits, infinity and 1887 | their negative variants were already introduced. Any noun can be 1888 | converted to a constant function by calling the rank operator with 1889 | infinity on it! 1890 | 1891 | ```J 1892 | explicit =: {{ NB. multiline 1893 | _9 1894 | : 1895 | 9 NB. typo 1896 | }} 1897 | specialFn =: _9: NB. only for digits, infinity and their negatives 1898 | tacit =: _9 "_ 1899 | verbs =: explicit ` specialFn ` tacit `:0 1900 | verbs 'as monads' 1901 | 'call' verbs 'as dyads' NB. note the typo from above 1902 | ``` 1903 | 1904 | ## Composition: 1905 | 1906 | On the interactive session prompt it is easy to pipe the result of one 1907 | verb into another verb: Simply put the second verb's name before the 1908 | first one's. However, it seems assigning this pipeline to a name does 1909 | not work (see: names), as it creates a train (see: trains). Instead, the 1910 | verbs need to be *composed* with a conjunction: 1911 | 1912 | ```J 1913 | < (1&+) 1 2 3 NB. box the incremented values 1914 | pipeline =: < (1&+) NB. creates a train 1915 | pipeline 1 2 3 NB. thus is not expected result 1916 | pipeline =: < @: (1&+) NB. this however does give expected result: 1917 | pipeline 1 2 3 1918 | ``` 1919 | 1920 | Each composition conjunction exists as **two variants**: One which 1921 | passes the whole argument/s to the pipeline (aka rank infinity) and ends 1922 | in ":" and one whose rank (mostly) depends on the rank of the first verb 1923 | of the pipeline, essentially applying the later verbs on each result 1924 | returned by the first verb, instead of the collected results. 1925 | 1926 | This calls a **monad on** the result of another **monad**. Note that the 1927 | usage of monadic pipelines created with `&` or `&:` is discouraged as 1928 | they are not recognized as performance optimized patterns! 1929 | ```J 1930 | NB. these are equivalent only when called monadically: 1931 | (B @: A) y = B A y 1932 | (B &: A) y = B A y NB. functionally equivalent but discouraged 1933 | NB. pipeline has monadic rank of A: 1934 | (B @ A) y = (B @: A)"A y 1935 | (B & A) y = (B &: A)"A y NB. functionally equivalent but discouraged 1936 | ``` 1937 | ```J 1938 | # @:(>"0) 1;2;3 NB. length of combined results 1939 | # @ (>"0) 1;2;3 NB. lengths of results 1940 | NB. functionally equivalent but discouraged: 1941 | # &:(>"0) 1;2;3 1942 | # & (>"0) 1;2;3 1943 | ``` 1944 | 1945 | Calling a **monad on** the result of a **dyad**: 1946 | ```J 1947 | x (B @: A) y = B x A y 1948 | NB. pipeline has dyadic ranks of A: 1949 | x (B @ A) y = x (B @: A)"A y 1950 | ``` 1951 | ```J 1952 | 1 2 3 < @:(,"0 0) 4 5 6 NB. box collected results 1953 | 1 2 3 < @ (,"0 0) 4 5 6 NB. box each result 1954 | 1 2 3 < @:(,"0 1) 4 5 6 1955 | 1 2 3 < @ (,"0 1) 4 5 6 1956 | ``` 1957 | 1958 | Call a **dyad on** the results of the **arguments individually 1959 | processed by a monad** like so: 1960 | ```J 1961 | x (B &: A) y = (A x) B (A y) 1962 | NB. pipeline (effectively B) has monadic rank of A (as dyadic rank): 1963 | x (B & A) y = x (B &: A)"({.A b.0) y NB. (A x) B"({.A b.0) (A y) 1964 | ``` 1965 | ```J 1966 | (1;2;3) ,&:(>"0) (4;5;6) NB. join unboxed args 1967 | (1;2;3) ,& (>"0) (4;5;6) NB. join atom pairs of unboxed args 1968 | (<"0 i.3 2) ;&:(>"1) (<"(0) 6+i.3 2) 1969 | (<"0 i.3 2) ;& (>"1) (<"(0) 6+i.3 2) 1970 | ``` 1971 | 1972 | `&.` and `&.:` work like `&` and `&:` (monad on monad or dyad on 1973 | result-pairs of arguments processed by monads) but **also apply the 1974 | inverse** (see: inverse and tacit functions) of the first verb as the 1975 | third verb in the pipeline! 1976 | ```J 1977 | (B &.: A) y = A^:_1 B A y 1978 | x (B &.: A) y = A^:_1 (A x) B (A y) 1979 | NB. the pipeline's rank/s are the mondic rank of A: 1980 | (B &. A) y = ((B &.: A)"A) y 1981 | x (B &. A) y = x (B &.: A)"({.A b.0) y 1982 | ``` 1983 | ```J 1984 | (1&+) &.:(>"0) (<"0 i.2 2) NB. unbox, increment, box collected results 1985 | (1&+) &. (>"0) (<"0 i.2 2) NB. unbox, increment, box each result 1986 | 1987 | ] Xb =: <"0 X =: 'ABCD' 1988 | ] Yb =: <"0 Y =: 'abcd' 1989 | Xb (,"_)&.:(>"0) Yb 1990 | Xb (,"_)&. (>"0) Yb 1991 | ``` 1992 | 1993 | If only one side needs processing, a 2-element gerund is used with an 1994 | empty box marking the side not to modify; the second verb now uses its 1995 | own monadic rank on the unprocessed side: 1996 | ```J 1997 | x B &.:(a:`A) y = A^:_1 x B (A y) 1998 | (x B &.:(A`a:) y = A^:_1 (A x) B y) 1999 | NB. pipeline's ranks: respecitve dyadic rank of B and monadic rank of A: 2000 | x B &. (a: `A) y = x B &.:(a:`A) "((1{B b.0),{.A b.0) y 2001 | (x B &. (A `a:) y = x B &.:(A`a:) "(({.A b.0),2{B b.0) y) 2002 | ``` 2003 | ```J 2004 | X (,"_ _ _)&.:(a:`(>"0)) Yb 2005 | X (,"_ _ _)&. (a:`(>"0)) Yb NB. !! 2006 | NB. The previous example was not the same as the version without gerund 2007 | NB. because the version with gerund uses one of B's own dyadic ranks, 2008 | NB. while the other version only used A's monadic rank for both sides 2009 | X (,"_ 0 _)&. (a:`(>"0)) Yb NB. this behaves like without gerund 2010 | 2011 | NB. when the noun to process is on the other side: 2012 | Xb (,"_ _ _)&.:((>"0)`a:) Y 2013 | Xb (,"_ _ _)&. ((>"0)`a:) Y 2014 | Xb (,"_ _ 0)&. ((>"0)`a:) Y 2015 | ``` 2016 | 2017 | # Appendix 2018 | 2019 | ## J shell scripts: 2020 | 2021 | J scripts are plaintext files, should use the extension `.ijs` and 2022 | may have a _shebang as first line_ (`#!` + the path to the J 2023 | executable). 2024 | 2025 | _Arguments_ to the script are saved as boxed strings in variable 2026 | `ARGV_z_` in elements 3 and higher; element 2 is the path of the script 2027 | (as used on the commandline) and the first and only argument which is 2028 | always available is the name of the command which invoked the process 2029 | (as used on the commandline; usually `jconsole`). Arguments to the J 2030 | interpreter, which are not passed to the script, are not listed in 2031 | `ARGV`. Thus in a script invoked like with 2032 | `../j9.4/bin/jconsole -noel ./file.ijs foo 123` has 2033 | `ARGV -: '../j9.4/bin/jconsole';'./file.ijs';'foo';'123'` while just 2034 | running the interpreter from PATH interactively (`jconsole`) only has 2035 | `ARGV -: <'jconsole'`. 2036 | 2037 | To access _environment variables_ use verb `getenv` which returns boolean 2038 | `0` if it is not defined. (Note: environment variables have to be 2039 | strings thus the boolean cannot be confused with a value `'0'`.) 2040 | 2041 | Use verbs `stdout` and `stderr` to write to these file-descriptors and 2042 | do _not_ append a newline (unlike `echo`). 2043 | 2044 | Stdin is interpreted as input to the **interactive session which starts 2045 | after the interpreter finished the supplied script** -- unless the 2046 | script prevents starting the interactive session by _terminating 2047 | explicitly_ with `exit` (takes the number which shall be the process' 2048 | exit/return code as argument), or _consumes stdin_ with verb `stdin`, 2049 | which returns it as a string. Since `stdin` and `stdout` are inverses, 2050 | outputting the transformation of user input can be written conveniently 2051 | using `&.`; for example the script `|. &. stdin ''` reverses the input 2052 | and could be executed like so: 2053 | `echo -n -e 'hello\nworld' | jconsole script.ijs` 2054 | A string can be split into boxed lines using monadic `cutopen`. 2055 | 2056 | ## String Representation and Unicode: 2057 | 2058 | Note: For this section to display properly a font with support for emoji 2059 | needs to be used. If in the terminal J does not accept input of 2060 | non-ASCII characters start it with the `-noel` parameter. 2061 | 2062 | J's default **string type**, "**literal**", treats 8 bits (1 byte) as an 2063 | atom. This works well for the first 128 ASCII characters, which are 2064 | equivalent to their UTF-8 representation and only need a single byte to 2065 | be stored. Other letters are represented by more bytes in UTF-8, which 2066 | makes them hard to work with. To fix this UCS-2 encodes every letter as 2067 | 2 bytes, which can be interpreted as 1 atom by using J's type 2068 | "**unicode**". However, when UTF-16 (UCS-2 superset) came one could not 2069 | rely on 1 glyph being 1 "unicode" atom anymore: it may be 2. Luckily 2070 | UCS-4, also called UTF-32, encodes every glyph with exactly 4 bytes, 2071 | which can be treated as a single atom with J's type "**unicode4**". Be 2072 | careful when converting to a representation with bigger atoms to use an 2073 | operation which merges surrogate pairs (the multiple atoms representing 2074 | a single glyph) into a single atom; when converting "unicode" to 2075 | "unicode4" J would still understand it but it would not be valid UTF-32. 2076 | 2077 | The verb `u:` provides access to unicode related functionality: 2078 | - monad `u: string` is `2 u: string` 2079 | - monad `u: number` is `4 u: number` 2080 | - dyad: left arg is: 2081 | 1. truncate to 1-byte precision 2082 | 2. extend or truncate to 2-byte precision 2083 | 3. convert to UCP (Unicode Code Point, a number) 2084 | 4. get UCP in UCS-2 range (<65536) as "unicode" 2085 | 5. like `1&u:` but raise error if discarding non-zero bits 2086 | 6. from literal UTF-16: each 2 bytes become 1 atom of type "unicode" 2087 | 7. convert (literal as UTF-8) to smallest string type needed; 2088 | get any UCP as "unicode" 2089 | 8. convert to UTF-8; 2090 | get any UCP as UTF-8 encoded "literal" 2091 | 9. convert string (literal as UTF-8) to type "unicode4" except when 2092 | all ASCII; 2093 | UCPs as "unicode4" (merges surrogate pairs) 2094 | 10. convert each *atom* of string to "unicode4", therefore this 2095 | does not give valid UTF-32 if surrogate pairs are present (fix 2096 | with 9&u:); 2097 | get any UCP as "unicode4" 2098 | 2099 | ```J 2100 | 2 5 $ 'helloworld' 2101 | 2 5 $ 'hellöwörld' NB. doesn't work because: 2102 | 3 u: 'ö' NB. ö is UTF-8 character represented by 2 atoms 2103 | 3 u: 7 u: 'ö' NB. convert to type unicode -> 1 atom 2104 | 2 5 $ 7 u:'hellöwörld' 2105 | 2 5$ 7 u:'hell😈w😈rld' NB. doesn't work because: 2106 | 3 u: 7 u: '😈' NB. emojis use 2 atoms in UTF-16 encoding 2107 | 3 u: 9 u: 7 u: '😈' NB. convert to type unicode4 -> 1 atom 2108 | 3 u:10 u: 7 u: '😈' NB. careful: 10&u: converts atoms individually: 2109 | NB. the UPCs are the same but use 4 bytes each 2110 | 3 u: 9 u: 10 u:7 u:'😈' NB. use 9&u: to fix such a unicode4 string 2111 | 2 5 $ 9 u:'hell😈w😈rld' 2112 | NB. convert each letter to UTF-8 encoded literal string and show bytes 2113 | < @ (3&u:) @ (8&u:) "(0) 9 u:'hell😈w😈rld' 2114 | NB. demo 7&u: converts to smallest string type needed for representation 2115 | datatype @ (7&u:) @ (8&u:) "(0) 9 u:'hell😈w😈rld' 2116 | datatype @ (7&u:) "(0) 9 u:'hell😈w😈rld' 2117 | NB. demo 9&u: converts to ASCII if possible else to unicode4 2118 | datatype @ (9&u:) @ (8&u:) "(0) 9 u:'hell😈w😈rld' 2119 | datatype @ (9&u:) "(0) 9 u:'hell😈w😈rld' 2120 | NB. extends or truncates to 2 byte procesion; this is not conversion! 2121 | 2 u: 9 u: '😈' NB. throws away one byte -> different glyph 2122 | datatype 2 u: 'a' 2123 | 2124 | NB. adding strings 2125 | datatype (7 u:'a'),(9 u:'b') 2126 | datatype (7 u:'ö'),(9 u:'a') 2127 | datatype (7 u:'a'),(9 u:'ö') 2128 | NB. mind surrogate pairs, use 9&u: to fix it: 2129 | 3 u: (7 u: '😈'), (9 u: '😈') 2130 | 3 u: 9 u: (7 u: '😈'), (9 u: '😈') 2131 | 2132 | NB. UCP to string 2133 | 4 u: 246 NB. to unicode string; ensures 1 glyph = 1 atom: 2134 | 4 u: 128520 NB. which is not true for UCPs >65535 2135 | 7 u: 128520 NB. to unicode string; might be 2 atoms 2136 | 9 u: 128520 NB. to unicode4 string 2137 | 3 u: 9 u: 55357 56840 NB. to unicode4 string, wont merge surrogates 2138 | 3 u:9 u:9 u:55357 56840 NB. use 9&u: to fix it 2139 | ``` 2140 | 2141 | ## Covered Builtins: 2142 | 2143 | "conjunct" = conjunction 2144 | ``` 2145 | comment NB. comment rest of line 2146 | noun _ infinity, but as number-prefix: negative sign 2147 | syntax () subexpressions are parenthesized 2148 | syntax '' string (which is a *list* of literals) 2149 | monad - negate-number (use -. (not) to negate booleans) 2150 | dyad - subtract 2151 | dyad , join lists 2152 | dyad + addition 2153 | monad + complex conjugate 2154 | adverb / puts verb between elements of new verb's arg/s 2155 | conjunct m&v convert dyad v to monadic verb with x fixed to m 2156 | conjunct u&n convert dyad u to monadic verb with y fixed to n 2157 | dyad ^ power: x to the y 2158 | assignment =: assign to global namespace 2159 | assignment =. try assigning to local namespace else to global 2160 | monad [ return argument unchanged 2161 | monad ] return argument unchanged 2162 | dyad [ return x unchanged 2163 | dyad ] return y unchanged 2164 | monad load executes file or shortname (alias for some file) 2165 | monad scripts show shortnames 2166 | monad loadd like load but print each line before executing 2167 | monad require like load but only if was not loaded already 2168 | conjunct : define entities 2169 | syntax ) end multiline explicit definition 2170 | monad echo output message 2171 | ambivalent __: _9: ... 0: ... 9: _: ignore arg/s and return digit 2172 | syntax : separate monadic and dyadic bodies 2173 | monad ": convert to displayable byte array 2174 | dyad * multiplication 2175 | dyad % division 2176 | monad % 1 divided by y 2177 | monad names pretty print names defined in current namespace 2178 | conjunct !: access lots of system functions 2179 | (dyad o. access to circle functions (sin, cos, ...) ) 2180 | syntax {{ opens a direct definition 2181 | syntax {{)n open direct definition of type n (or a, c, m, d) 2182 | syntax }} close DD 2183 | monad $ get shape 2184 | monad # get length 2185 | dyad $ reshape array 2186 | monad < box 2187 | monad > unbox/open 2188 | noun a: empty box 2189 | dyad ; join as boxes 2190 | dyad = compares corresponding atoms 2191 | syntax assert. error if not all 1s 2192 | syntax if. if block ends at do. 2193 | syntax do. ends a condition block 2194 | syntax elseif. else-if block ends at do. 2195 | syntax else. else block ends at end. 2196 | syntax end. ends a control structure 2197 | syntax select. target value/s to match against; ends at f/case. 2198 | syntax case. test value/s to match target; ends at do. 2199 | syntax fcase. like case. but invoces next f/case.; ends at do. 2200 | dyad > is x greater than y? 2201 | syntax while. checks condition before every loop; ends at do. 2202 | syntax whilst. like while. but runs at least once; ends at do. 2203 | syntax for. loop once for each item in clause; ends at do. 2204 | syntax for_var. like for. but sets var to item 2205 | syntax return. return last value or *left* arg 2206 | verb 9!:8 returns list of default error messages 2207 | verb dberr return last error's number 2208 | verb dberm return last error's message 2209 | verb dbsig equivalent to (13!:8) 2210 | verb 13!:8 raise error y; optional: custom message x 2211 | syntax try. handle errors in block; ends at catch/d/t. 2212 | syntax catch. handle normal errors (not error 55 = throw.s) 2213 | verb dbr disable (arg 0) or enable (1) debugging mode 2214 | verb dbq query debugging mode state 2215 | verb dbs shows debug stack 2216 | verb dbnxt continue program on next line 2217 | syntax catchd. replacement for catch. pauses when debugging 2218 | syntax throw. exit fn, goes up callstack until finds catcht. 2219 | syntax catcht. handles error 55 (throw.s) in *called* functions 2220 | monad i. get integer sequence in shape of argument 2221 | adverb b. call with arg 0 to show ranks of verb 2222 | conjunct " change ranks of verb 2223 | adverb ~ swap arguments or copy right arg to left side 2224 | syntax [: x?([: B A)y becomes (B x?Ay) 2225 | conjunct ` make list of verbs (gerund) 2226 | conjunct `: execute a gerund in a certain way 2227 | monad conl boxed list of namespaces 2228 | monad coname get name of current namespace 2229 | monad cocurrent switch to namespace 2230 | monad nl boxed list of names defined in current namespace 2231 | monad clear remove names defined in given/'base' namespace 2232 | monad copath ancestors of *given* namespace 2233 | adverb f. pull name into current namespace 2234 | monad erase remove given names from *their* namespace 2235 | operand u. resolves modifier's operand u in caller's scope 2236 | operand v. resolves modifier's operand v in caller's scope 2237 | monad conew create new instance of class 2238 | monad cocreate creates new namespace, numeric if empty y 2239 | dyad conew create new instance and pass x as args to create 2240 | monad codestroy remove current namespace 2241 | monad coerase remove namespace 2242 | monad coclass switch to namespace 2243 | dyad copath set ancestors of namespace 2244 | monad coinsert prepend ancestors of current namespace 2245 | dyad { index into array 2246 | adverb } return copy of array with replaced elements 2247 | dyad # repeat curresponding elements x-times 2248 | monad , flatten array; scalar becomes list 2249 | monad {: last element 2250 | monad {. first element 2251 | dyad {. first/last x elements 2252 | monad }: except last element 2253 | monad }. except first element 2254 | dyad }. except first/last x elements 2255 | dyad {:: index into boxed structure 2256 | conjunct m@.n index gerund m 2257 | monad break abort exec in session with given or default tag 2258 | conjunct x m&v y apply monad m&v x-times 2259 | conjunct x u&n y apply monad u&n x-times 2260 | conjunct u^:n apply u or (x&u if x given) n-times 2261 | conjunct u^:v call v on arg/s to get amount of repetitions 2262 | conjunct m@.v call v on arg/s to get index of verb in m to run 2263 | conjunct F. infinite fold single 2264 | conjunct F: infinite fold multiple 2265 | dyad Z: exit fold according to x; do nothing if y is 0 2266 | conjunct F.. fold single forward 2267 | conjunct F.: fold single reverse 2268 | conjunct F:. fold multiple forward 2269 | conjunct F:: fold multiple reverse 2270 | conjunct :: if left verb throws run right verb 2271 | adverb b. call with arg _1 to show inverse 2272 | conjunct :. right verb is inverse of left verb 2273 | conjunct 13 : tries to convert function body to tacit verb 2274 | conjunct @: as monad: monad>monad; as dyad: dyad>monad 2275 | conjunct @ like @: but calls left on each subresult 2276 | conjunct &: as dyad: monads>dyad; as monad: like @: 2277 | conjunct & like &: but calls left on each subresult 2278 | conjunct &.: like &: but finally calls inverse of right verb 2279 | conjunct &. like &.: but call left>inverse on each subresult 2280 | noun ARGV_z_ process name; [script name; [script arg1; ...]] 2281 | monad getenv return environment variable y or 0 if undefined 2282 | monad stdout write y to stdout (does not append newline) 2283 | monad stderr write y to stderr (does not append newline) 2284 | monad exit terminate J with exit code y (integer: 0-255) 2285 | monad stdin consume stdin and return it as string 2286 | monad cutopen split string y into boxed lines 2287 | monad u: 2&u: or 4&u: 2288 | dyad u: provides access to some unicode functions 2289 | monad datatype type of noun as words 2290 | ``` 2291 | --------------------------------------------------------------------------------