
- •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
1. Introduction
This book will tell you enough about J for you to use it as a language for developing serious applications, but it is about more than learning the J language: it is also about 'thinking big' in programming, and how programming in J is fundamentally different from programming in C. C programs deal intimately with scalars (single numbers and characters), and even when they combine those scalars into arrays and structures, the operations on the arrays and structures are defined by operations on the scalars. To ensure that each item of an array is operated on, loops are created that visit each element of the array and perform a scalar operation on the element.
Writing code in a scalar language makes you rather like a general who gives orders to his troops by visiting each one and whispering in his ear. That touch-of-Harry kind of generalling can achieve victorious results, and it has the advantage that the orders can be tailored to the man, but its disadvantages are significant: the general spends much mental energy in formulating individual orders and much breath in communicating them individually; more significant, his limited attention is drawn toward individuals and away from the army as a whole. Even the great Rommel was overtaxed at times.
The J programmer is, in contrast, a general who stands before his army and snaps out orders to the army as a whole. Every man receives the same order, but the order itself contains enough detail for the individual men to act appropriately. Such a general can command a corps as easily as a platoon, and always has the 'big picture' in mind.
OK, maybe you're not Rommel, but you are a working programmer, and you suspect that very few practical programs can be represented as array operations—matrix multiplication maybe, or adding a list of numbers—and that, even if a wide range of programs were possible, the set of operations supported must be too vast to be practical: wouldn't we need an array operation for every possible program?
The first half of this book is devoted to showing you that it is indeed possible to write meaningful programs with array operations. We take the approach of looking at the different ways loops are used, and seeing what facilities J has for producing the same result using array operations. We will find that J contains a couple of dozen arrayprocessing primitives and a dozen or so very cleverly chosen pipe-fittings that allow those primitives to be connected together to provide the limitless supply of arrayprocessing functions needed for practical programming.
Interspersed with the elaboration of more and more intricate array operations are treatments of other matters of use in practical programming: structure definition, input and output, performance measurement, calling DLLs, modular programming. Eventually we will see how to use if-then-else and do-while in J, though you will have learned more elegant ways to get the same results.
The last portion of the book is devoted to the optional topic of tacit programming, J's language for functional programming. Tacit programming is an extremely terse way of expressing algorithms, one that allows programs that have been compressed from a page of C into a few lines of J to be compressed still further.
1
2. Culture Shock
A C Programmer's First Thoughts On J
This doesn't look like a program. Where did the program go?
You have gotten used to the pace and structure of C. You can recognize a loop, you figure out what the loop is doing, you see what variables it sets. The assignments and the loops are signposts that direct your analysis of code.
In J, every operator has a loop built in, so they don't jump out at you in the same way. And because the syntax of J is so terse, and arrays use the same syntax as single variables, there is much less need for temporary variables.
Here's an example. Figure out what the following code does:
int i, j, maxcol = 0; float maxval = x[0][0]; for(i = 0;i<=xsize0;++i) {
for(j = 0;j<=xsize1;++j) { if(x[i][j] > maxval) {
maxval = x[i][j]; maxcol = j;
}
}
}
Not too hard. When the code finishes, maxval is the largest element in the array x, and maxcol is the column number it was in. As it happens, all I wanted was the column number, but there was no way for you to know that.
The same code in J:
maxcol =. (i. >./) >./ x
With some practice, you will learn to read this code just as easily as you read the C. You will recognize the / as an indicator of a loop, and the i. as an indicator for a search.
What happened to the if statement?
It's built into the >. primitive. Just as most loops are hidden inside primitives, so are most conditionals. The functions you write can also contain built-in conditionals.
What's the statement delimiter?
There isn't one. Statements are exactly one line long.
2
I've looked at some J code. Every other character is a period or a colon. I've got spots before my eyes. How can anybody read this stuff?
You'll get used to it. J has a great many primitives, and it's important to keep the names short so that you can fit a lot of computation on one line; so the names are either single characters, like >, or a character with a period or space appended (>. and >:). The period/colon is just part of the name. Single letters with period/colon, like i., are also used for primitives. If you want to assign your own names to the primitives, you are allowed to, but pretty soon you'll want to go back to the shorter names to save space and typing.
Where are the declarations? Doesn't J use arrays? How do I know what the type of a variable is?
Oh yeah, J uses arrays. Any variable can be an array. As for what the type and dimensioning is: you assigned the variable, didn't you? It contains whatever you put into it, a number, a string, an array, a structure... J will remember. If your program logic requires you to find out the current attributes of a variable, J can tell you.
Every J program, both primitives and programs that you write, can automatically be applied to arrays. The carefully-thought-out way this is done is one of the prime strengths of J. The statement
x + y
means 'add x to y'; it will do that if x and y are single numbers, or if they are multidimensional arrays. The looping needed to operate on the individual numbers is built into the language, not into your program.
I've looked at a line of J code and it's just a mess with no discernible syntax.
Something like
lifodd =. ]`[@.(2&|@[)
perhaps, a program that returns the left operand if it is odd, otherwise the right operand? Patience. Every character has a meaning, even the ` " [ ] { } characters which act individually, not as pairs. Learn what they mean and all will become clear.
I ran across this line: 1 2 + 3. What's with the extra number floating in space?
1 2 is a one-dimensional array of 2 numbers with the values 1 and 2. Arrays come up so much in J that we use this shorthand to define one without requiring any more syntax than just the values of the elements of the array.
I've looked at a line of J code and I'm absolutely sure there are no variables in it at all. How can that mean anything?
Oh, you've stumbled onto a tacit program, which describes its computation without referring to any variables, not even symbolic parameters. The classic teaching example is
mean =: +/ % #
which the mean of an array of numbers. Tacit programs are considered an advanced topic in this book, and are covered in a section at the end. They are the ultimate in
3
concise expression; many J programmers favor them for that reason, but you can wait to learn about them until you've learned simple J.
In the examples all I see are things that contain =:, which I'm guessing are assignment statements. How do I write a program?
Some of the assignment statements are programs. In J, a name becomes a function name when you assign it a value that is a function.
Once I've written a program, how do I run it? I don't see anything that looks like a function call.
In J, there is no special syntax for a function call. Just as you perform the 'minus' function with - y or the 'subtract' function with x - y, you invoke a user-defined function by typing its name before or between its operands:
x DifferenceSquared y or FindPrimeGreaterThan 1000.
How do I compile my program?
You don't. J is interpreted. As soon as you type your program in (or read it in from a file), it's ready to use. Here's a starter program:
h =: verb : '''Hello world.'''
Type that (note the triple quotes), then run it with h ''
The triple quotes are ugly.
Quit bellyaching. Read the book and you'll learn how to avoid them. Remember those 10 lines of C that were replaced by a quarter-line of J, and learn how to do that yourself.
4
Programming In J
5