
- •Foreword
- •1. Introduction
- •2. Culture Shock
- •3. Preliminaries
- •Notation Used in This Book
- •Terminology
- •Sentences (statements)
- •Word Formation (tokenizing rules)
- •Numbers
- •Characters
- •Valence of Verbs (Binary and Unary Operators)
- •How Names (Identifiers) Get Assigned
- •Order of Evaluation
- •How Names Are Substituted
- •What a verb (function) looks like
- •Running a J program
- •The Execution Window; Script Windows
- •Names Defined at Startup
- •Step-By-Step Learning: Labs
- •J Documentation
- •Getting Help
- •4. A First Look At J Programs
- •Average Daily Balance
- •Calculating Chebyshev Coefficients
- •5. Declarations
- •Arrays
- •Cells
- •Phrases To Memorize
- •Constant Lists
- •Array-creating Verbs
- •6. Loopless Code I—Verbs Have Rank
- •Examples of Implicit Loops
- •The Concept of Verb Rank
- •Verb Execution—How Rank Is Used (Monads)
- •Controlling Verb Execution By Specifying a Rank
- •Examples Of Verb Rank
- •Negative Verb Rank
- •Verb Execution—How Rank Is Used (Dyads)
- •When Dyad Frames Differ: Operand Agreement
- •Order of Execution in Implied Loops
- •A Mistake To Avoid
- •7. Starting To Write In J
- •8. More Verbs
- •Arithmetic Dyads
- •Boolean Dyads
- •Min and Max Dyads
- •Arithmetic Monads
- •Boolean Monad
- •Operations on Arrays
- •9. Loopless Code II—Adverbs / and ~
- •Modifiers
- •The Adverb Monad u/
- •The adverb ~
- •10. Continuing to Write in J
- •11. Boxing (structures)
- •Terminology
- •Boxing As an Equivalent For Structures In C
- •12. Compound Verbs
- •Verb Sequences—u@:v and u@v
- •Making a Monad Into a Dyad: The Verbs [ and ]
- •Making a Dyad Into a Monad: u&n and m&v
- •13. Empty Operands
- •Execution On a Cell Of Fills
- •Empty cells
- •If Fill-Cells Are Not Enough
- •14. Loopless Code III—Adverbs \ and \.
- •15. Verbs for Arithmetic
- •Dyads
- •Monads (all rank 0)
- •16. Loopless Code IV
- •A Few J Tricks
- •Power/If/DoWhile Conjunction u^:n and u^:v
- •Tie and Agenda (switch)
- •17. More Verbs For Boxes
- •Dyad ; (Link) And Monad ; (Raze)
- •Dyad { Revisited: the Full Story
- •Split String Into J Words: Monad ;:
- •Fetch From Structure: Dyad {::
- •Report Boxing Level: Monad L.
- •18. Verb-Definition Revisited
- •What really happens during m :n and verb define
- •Compound Verbs Can Be Assigned
- •Dual-Valence verbs: u :v
- •The Suicide Verb [:
- •Multi-Line Comments Using 0 :0
- •Final Reminder
- •The Obverse u^:_1
- •Apply Under Transformation: u&.v and u&.:v
- •Defined obverses: u :.v
- •An observation about dyadic verbs
- •20. Performance: Measurement & Tips
- •Timing Individual Sentences
- •Compounds Recognized by the Interpreter
- •Use Large Verb-Ranks! and Integrated Rank Support
- •Shining a Light: The J Performance Monitor
- •21. Input And Output
- •Foreigns
- •File Operations 1!:n; Error Handling
- •Treating a File as a Noun: Mapped Files
- •Format Data For Printing: Monad And Dyad ":
- •Format an Array: 8!:n
- •Format binary data: 3!:n
- •printf, sprintf, and qprintf
- •Convert Character To Numeric: Dyad ".
- •22. Calling a DLL Under Windows
- •Memory Management
- •Aliasing of Variables
- •23. Socket Programming
- •Asynchronous Sockets and socket_handler
- •Names and IP Addresses
- •Connecting
- •Listening
- •Other Socket Verbs
- •24. Loopless Code V—Partitions
- •Find Unique Items: Monad ~. and Monad ~:
- •Apply On Subsets: Dyad u/.
- •Apply On Partitions: Monad u;.1 and u;.2
- •Apply On Specified Partitions: Dyad u;.1 and u;.2
- •Apply On Subarray: Dyad u;.0
- •Apply On All Subarrays: Dyad u;.3 and u;._3
- •Extracting Variable-Length Fields Using ^: and ;.1
- •Example: Combining Adjacent Boxes
- •25. When Programs Are Data
- •Calling a Published Name
- •Using the Argument To a Modifier
- •Invoking a Gerund: m`:6
- •Passing the Definition Of a Verb: 128!:2 (Apply)
- •Passing an Executable Sentence: Monad ". and 5!:5
- •26. Loopless Code VI
- •28. Modifying an array: m}
- •Monad I.—Indexes of the 1s in a Boolean Vector
- •29. Control Structures
- •while./do./end. and whilst./do./end.
- •if./do./else./end., if./do./elseif./do./end.
- •try./catch./catcht./end. and throw.
- •return.
- •assert.
- •30. Modular Code
- •Locales And Locatives
- •Assignment
- •Name Lookup
- •Changing The Current Locale
- •The Shared Locale 'z'
- •Using Locales
- •31. Writing Your Own Modifiers
- •Modifiers That Do Not Refer To x. Or y.
- •Modifiers That Refer To x. Or y.
- •32. Applied Mathematics in J
- •Complex Numbers
- •Matrix Operations
- •Calculus: d., D., D:, and p..
- •Taylor Series: t., t:, and T.
- •Hypergeometric Function with H.
- •Sparse Arrays: Monad and Dyad $.
- •Random Numbers: ?
- •Computational Addons
- •Useful Scripts Supplied With J
- •33. Elementary Mathematics in J
- •Verbs for Mathematics
- •Extended Integers, Rational Numbers, and x:
- •Factors and Primes: Monad p:, Monad and Dyad q:
- •Permutations: A. and C.
- •34. Graphics
- •Plot Package
- •2D Graphics: the gl2 Library
- •Displaying Tabular Data: the Grid Control
- •3D Graphics: OpenGL
- •35. Odds And Ends
- •Dyad # Revisited
- •Boxed words to string: Monad ;:^:_1
- •Spread: #^:_1
- •Choose From Lists Item-By-Item: monad m}
- •Recursion: $:
- •Make a Table: Adverb dyad u/
- •Cartesian Product: Monad {
- •Boolean Functions: Dyad m b.
- •Operations Inside Boxes: u L: n, u S: n
- •Comparison Tolerance !.f
- •Right Shift: Monad |.!.f
- •Generalized Transpose: Dyad |:
- •Monad i: and Dyad i:
- •Fast String Searching: s: (Symbols)
- •Fast Searching: m&i.
- •CRC Calculation
- •Unicode Characters: u:
- •Window Driver And Form Editor
- •Tacit Programming
- •36. Tacit Programs
- •37. First Look At Forks
- •38. Parsing and Execution I
- •39. Parsing and Execution II
- •The Parsing Table
- •Examples Of Parsing And Execution
- •Undefined Words
- •40. Forks, Hooks, and Compound Adverbs
- •Tacit and Compound Adverbs
- •Referring To a Noun In a Tacit Verb
- •41. Readable Tacit Definitions
- •Flatten a Verb: Adverb f.
- •Special Verb-Forms Used in Tacit Definitions
- •43. Common Mistakes
- •Mechanics
- •Programming Errors
- •44. Valedictory
- •45. Glossary
- •46. Error Messages
- •47. Index
35. Odds And Ends
To keep my discussion from wandering too far afield I left out a number of useful features of J. I will discuss some of them briefly here.
Dyad # Revisited
x # y does not require that x be a Boolean list. The items of x actually tell how many copies of the corresponding item of y to include in the result:
1 2 0 2 # 5 6 7 8
5 6 6 8 8
Boolean x, used for simple selection, is a special case. If an item of x is complex, the imaginary part tells how many cells of fill to insert after making the copies of the item of y . The fill atom is the usual 0, ' ', or a: depending on the type of y, but the fit conjunction !.f may be used to specify f as the fill:
1j2 1 0j1 2 # 5 6 7 8
5 0 0 6 0 8 8
1j2 1 0j1 2 (#!.99) 5 6 7 8
5 99 99 6 99 8 8
Finally, a scalar x is replicated to the length of y . This is a good way to take all items of y if x is 1, or no items if x is 0 .
Boxed words to string: Monad ;:^:_1
;:^:_1 y converts y from a list of boxed strings to a single character string with spaces between the boxed strings.
;:^:_1 ('a';'list';'of';'words') a list of words
Spread: #^:_1
x #^:_1 y creates an array with the items of y in the positions corresponding to nonzero items of the Boolean vector x, and fills in the other items. +/x must equal #y .
1 1 0 0 1 #^:_1 'abc' ab c
You can specify a fill atom, but if you do you must bond x to # rather than giving it as a left operand:
1 1 0 0 1^:_1!.'x' 'abc' abxxc
Choose From Lists Item-By-Item: monad m}
Suppose you have two arrays a and b and a Boolean list m, and you want to create a composite list from a and b using each item of m to select the corresponding item of either a (if the item of m is 0) or b (if 1). You could simply write
207
m {"_1 a ,. b
and have the answer. There's nothing wrong with that, but J has a little doodad that is faster and uses less space, as long as you want to assign the result to a name. You write
name =. m} a ,: b
(assignment with =: works too). This form does not create the intermediate result from dyad ,: . If name is the same as a or b, the whole operation is done in-place.
More than two arrays may be merged this way, using the form name =. m} a , b , … ,: c
in which each item of m selects from one of a, b, …, c . The operation is not done inplace but it avoids forming the intermediate result.
Recursion: $:
In tacit verbs, recursion can be performed elegantly using the verb $:, which stands for the longest verb-phrase it appears in (that is, the anonymous verb, created by parsing the sentence containing the $:, whose execution resulted in executing the $:).
Recursion is customarily demonstrated with the factorial function, which we can write as: factorial =: (* factorial@<:) ^: (1&<)
factorial 4
24
factorial(n) is defined as n*factorial(n-1), except that factorial(1) is 1. Here we just wrote out the recursion by referring to factorial by name. Using $:, we can recur without a name:
(* $:@<:) ^: (1&<) 4
24
$: stands for the whole verb containing the $:, namely (* $:@<:) ^: (1&<) .
Make a Table: Adverb dyad u/
x u/ y is x u"(lu,_) y where lu is the left rank of u . Thus, each cell of x individually, and the entire y, are supplied as operands to u .
The definition is simplicity itself, and yet many J programmers stumble learning it. I think the problem comes from learning dyad u/ by the example of a multiplication table.
The key is to note that each cell of x is applied to the entire y : cell, not item or atom. The rank of a cell depends on the left rank of u . The multiplication table comes from a verb with rank 0:
1 2 3 */ 1 2 3
1 2 3
2 4 6
3 6 9
You can control the result by specifying the rank of u :
208
0 |
1 |
(i. 2 2) |
,"1/ 8 |
9 |
|
|
8 |
9 |
|
|
|
||
2 |
3 |
8 |
9 |
,"0 _/ |
8 |
9 |
0 |
8 |
(i. 2 2) |
||||
9 |
|
|
|
|
||
1 |
8 |
9 |
|
|
|
|
2 |
8 |
9 |
|
|
|
|
3 |
8 |
9 |
|
|
|
|
|
These results follow directly from the definition of dyad u/ . fndisplay shows |
|
the details: |
|
|
|
defverbs 'comma' |
|
+ |
(i. 2 2) comma"1/ 8 9 |
+ |
---------------+--------------- |
||
|(0 1) comma 8 9|(2 3) comma 8 9| |
||
+--------------- |
+--------------- |
+ |
+ |
(i. 2 2) comma"0 _/ 8 9 |
|
+ |
+ |
|
|0 comma 8 9|1 comma 8 9| |
||
+----------- ----------- |
+ |
+ |
|2 comma 8 9|3 comma 8 9| |
||
+----------- ----------- |
+ |
+ |
Cartesian Product: Monad { |
||
|
The cartesian product x×y of two sets x and y is the set of all combinations (a,b) |
|
where a is an element of x and b is an element of y . The cartesian product can be |
written in J as ,"_1 " _1 (or, if the items have rank 0, by the table adverb ,"0/), as seen in this example where we box each result:
'io' <@,"_1 " _1 'nfd' +--+--+
|in|on| +--+--+ |if|of| +--+--+ |id|od| +--+--+
Monad { takes a list of boxes y, where each box contains a set, and produces the cartesian product of the atoms of all the sets, with each combination boxed. The leading atom of the first set is concatenated with each atom of the second set in turn, each combination being boxed, and then the next atom of the first set is concatenated with each item of the second set, and so on until the first set is exhausted. Then, if there are more sets, each is processed in turn, with each atom of the new set being appended, inside the box, to each atom of the previous product. If you follow this description, you will see that the shape of the result will be ; $&.> y . To make sure you understand,
209
verify for yourself the results of { 'pl';'aio';'ntp' and
{ (i. 2 3);(i. 3 2) .
Boolean Functions: Dyad m b.
Functions on Boolean operands
I will just illustrate Boolean dyad m b. by example. m b. is a verb with rank 0. m, when in the range 0-15, selects the Boolean function:
9 b./~ 0 1
1 0
0 1
u/~ 0 1 is the function table with x values running down the left and y values running along the top. 9 is 1001 binary (in J, 2b1001), and the function table of 9 b. is
1 0 0 1 if you enfile it into a vector. Similarly:
, 14 b./~ 0 1 1 1 1 0
You can use m b. in place of combinations of Boolean verbs. Unfortunately, comparison verbs like > and <: have better performance than m b., so you may have to pay a performance penalty if you write, for example, 2 b. instead of >, even though they give the same results on Booleans:
>/~ 0 1
00
10
J verb-equivalents for the cases of m b. are: 0 0"0; 1 *.; 2 >; 3 ["0; 4 <; 5 ]"0; 6 ~:; 7 +.; 8 +:; 9 =; 10 -.@]"0; 11 >:; 12 -.@["0; 13 <:; 14 *:; 15 1"0 .
Bitwise Boolean Operations on Integers
When m is in the range 16-31, dyad m b. specifies a bitwise Boolean operation in which the operation (m-16) b. is applied to corresponding bits of x and y . Since 6 b. is exclusive OR, 22 b. is bitwise exclusive OR:
5 (22 b.) 7
2
The XOR operation is performed bit-by-bit.
Dyad 32 b. is bitwise left rotate: bits shifted off the end of the word are shifted into vacated positions at the other end.
Dyad 33 b. is bitwise unsigned left shift. x is the number of bits to shift y (positive x shifts left; negative x shifts right; in both cases zeros are shifted into vacated bit positions):
2 (33 b.) 5
20
Dyad 34 b. is bitwise signed left shift: it differs from the unsigned shift only when x and y are both negative (i. e. right shift of a negative number), in which case the vacated bit positions are filled with 1).
210