J For C Programmers Henry Rich Instant Download
J For C Programmers Henry Rich Instant Download
https://ebookbell.com/product/j-for-c-programmers-henry-
rich-1054122
https://ebookbell.com/product/c-for-programmers-with-an-introduction-
to-c11-c11-2016th-edition-paul-j-deitel-67733738
https://ebookbell.com/product/c-for-programmers-contains-240-examples-
deitel-harvey-m-deitel-21999956
C 2010 For Programmers 4th Edition Deitel Developer Series 4th Edition
Paul J Deitel
https://ebookbell.com/product/c-2010-for-programmers-4th-edition-
deitel-developer-series-4th-edition-paul-j-deitel-2011594
https://ebookbell.com/product/c11-for-programmers-paul-j-deitel-
harvey-m-deitel-37011420
C11 For Programmers 2nd Edition Paul J Deitel Harvey M Deitel
https://ebookbell.com/product/c11-for-programmers-2nd-edition-paul-j-
deitel-harvey-m-deitel-4658286
https://ebookbell.com/product/c11-for-programmers-paul-j-deitel-paul-
j-harvey-m-deitel-35996122
https://ebookbell.com/product/c-2012-for-programmers-5th-edition-
deitel-developer-series-paul-j-deitel-harvey-m-deitel-80211462
https://ebookbell.com/product/c11-for-programmers-c112-2016th-edition-
paul-j-deitel-231608280
https://ebookbell.com/product/tcpip-sockets-in-c-practical-guide-for-
programmers-2nd-edition-michael-j-donahoo-kenneth-l-calvert-33554962
J
For C Programmers
Henry Rich
2006/01/25 (J6.01)
Copyright © 2004 Henry H. Rich. All rights reserved.
Send comments to HenryHRich@nc.rr.com
Foreword
You are an experienced C programmer who has heard about J, and you think you'd
like to see what it's all about. Congratulations! You have made a decision that will
change your programming life, if only you see it through. The purpose of this book is to
help you do that.
It won't be easy, and it certainly won't be what you're expecting. You've learned
languages before, and you know the drill: find out how variables are declared, learn the
syntax for conditionals and loops, learn how to call a function, get a couple of examples
to edit, and you're a coder. Fuggeddaboutit! In J, there are no declarations, seldom will
you see a loop, and conditionals often go incognito. As for coding from examples, well,
most of our examples are only a couple of lines of code—you won't get much momentum
from that! You're just going to have to grit your teeth and learn a completely new way to
write programs.
Why should you bother? To begin with, for the productivity. J programs are usually
a fifth to a tenth as long as corresponding C programs, and along with that economy of
expression comes coding speed. Next, for the programming environment: J is an
interpreted language, so your programs will never crash, you can modify code while it's
running, you don't have to deal with makefiles and linking, and you can test your code
simply by entering it at the keyboard and seeing what it does.
If you stick with it, J won't just help the way you code, it'll help the way you think. C
is a computer language; it lets you control the things the computer does. J is a language
of computation: it lets you describe what needs to be done without getting bogged down
in details (but in those details, the efficiency of its algorithms is extraordinary). Because
J expressions deal with large blocks of data, you will stop thinking of individual numbers
and start thinking at a larger scale. Confronted with a problem, you will immediately
break it down into pieces of the proper size and express the solution in J—and if you can
express the problem, you have a J program, and your problem is solved.
Unfortunately, it seems to be the case that the more experience you have as a C
programmer, the less likely you are to switch to J. This may not be because prolonged
exposure to C code limits your vision and contracts the scope of your thinking to the size
of a 32-bit word—though studies to check that are still under way and it might be wise
for you to stop before it's too late—but because the better you are at C, the more you have
to lose by switching to J. You have developed a number of coding habits: for example,
how to manage loops to avoid errors at extreme cases; how to manage pointers
effectively; how to use type-checking to avoid errors. None of that will be applicable to
J. J will take advantage of your skill in grasping the essence of a problem—indeed, it
will develop that skill considerably by making it easier for you to express what you
grasp—but you will go through a period during which it will seem like it takes forever to
get things done.
During that period, please remember that to justify your choice of J, you don't have to
be as expert in J as you were in C; you only have to be more productive in J than you
ii
were in C. That might well happen within a month. After you have fully learned J, it
will usually be your first choice for describing a program.
Becoming a J programmer doesn't mean you'll have to give up C completely; every
language has its place. In the cases where you want to write code in C (either to use a
library you have in C or to write a DLL for a function that is inefficiently computed in J),
you will find interfacing J to DLLs to be simple and effective.
This book's goal is to explain rudimentary J using language familiar to a C
programmer. After you finish reading it, you should do yourself the honor of carefully
reading the J Dictionary, in which you can learn the full language, one of the great
creations in computer science and mathematics.
Acknowledgements
I am obliged to the reviewers who commented on earlier versions: Michel Dumontier,
Ken Iverson, Fraser Jackson, David Ness, Richard Payne, Ewart Shaw, and Keith Smillie.
Brian Schott, Nicholas Spies, and Norman Thomson exchanged emails with me at length
to smooth over rough spots. David Steele conducted a painstaking review of several
early drafts and suggested many changes great and small. Björn Helgason translated the
text into Icelandic, finding a number of errors along the way. Kip Murray's 'review'
became more of a dismantling, cleaning, and reassembly operation in which large
sections of prose were rewritten as he pointed out to me their essential meaninglessness;
the reader should be as grateful to him as I am.
Without the patient explanations of my early teachers in J, Raul Miller and Martin
Neitzel, I would have given up on J. I hope that this book pays to others the debt I owe to
them.
My current happy career as a J programmer would not have been possible without the
work of the staff at Jsoftware, Inc., who created J. For the patriarch, the late Ken Iverson,
I am unworthy to express admiration: I have only awe. I hope his achievement eases the
lives of programmers for generations to come. To the rest, both Iversons and non-
Iversons, I give my thanks.
The implementation of the J interpreter has required diverse skills: architectural
vision, careful selection of algorithms, cold-eyed project management to select features
for implementation, robust and efficient coding, performance optimization, and expertise
in numerical analysis. Most improbably, all these talents have resided in one man, Roger
Hui il miglior fabbro. J gives us all a way to have a little of Roger's code in our own.
We should aspire no higher.
Change History
2002/6/18: Add chapters on mathematics in J, and section on Symbols; minor changes to
wording; bring text up to J Release 5.01
2002/8/16: Minor additions; added section on aliasing; added chapter on sockets
2002/9/26: Added sections on fndisplay, integrated rank support, and ordering of implied
loops
iii
2002/11/14 Added explanatory sections, section on the J Performance Monitor, and
chapter on Error Messages
2003/07/18 (J5.03) added section on I., updated f. . Added chapter on frequent errors.
Added section on run-length decoding
2004/10/31 (J5.04) ^:a:, vector cut. Added chapter on Sequential Machines
2004/11/22 Added section on monad {
2005/04/14 Fixed discussion of throw.
2005/09/03 (J6.01) added chapter on Graphics, discussion of noun forks, section on Fast
Searching, section on CRC. Switched chapters 10 & 11, and added pictorial
discussion of @ and @: . Added example on partitions. Added section on 3!:4 5
conversions. Explained the difference between (number number) and (noun noun).
2005/01/25 Account for 6.01 changes. Describe dyad I.
iv
Contents
Foreword ............................................................................................................................. ii
Acknowledgements.................................................................................................. iii
Change History ........................................................................................................ iii
1. Introduction................................................................................................................... 1
2. Culture Shock................................................................................................................ 2
Programming In J 5
3. Preliminaries ................................................................................................................. 6
Notation Used in This Book ..................................................................................... 6
Terminology.............................................................................................................. 6
Sentences (statements) ........................................................................................... 7
Word Formation (tokenizing rules) ........................................................................ 7
Numbers.................................................................................................................... 8
Adjacent Numbers Form a Single Word .............................................................. 8
Adjacent Named Nouns Do NOT Form a Single Word....................................... 9
Characters ................................................................................................................. 9
Valence of Verbs (Binary and Unary Operators) ................................................. 9
How Names (Identifiers) Get Assigned................................................................. 10
Order of Evaluation ................................................................................................ 10
How Names Are Substituted................................................................................... 11
What a verb (function) looks like........................................................................... 12
Running a J program............................................................................................... 13
Interrupting Execution........................................................................................ 14
Errors .................................................................................................................. 14
The Execution Window; Script Windows .............................................................. 14
Names Defined at Startup ....................................................................................... 15
Step-By-Step Learning: Labs.................................................................................. 15
J Documentation ..................................................................................................... 16
Getting Help............................................................................................................ 16
4. A First Look At J Programs ........................................................................................ 17
Average Daily Balance ........................................................................................... 17
Calculating Chebyshev Coefficients....................................................................... 20
5. Declarations ................................................................................................................ 22
Arrays...................................................................................................................... 22
Cells ........................................................................................................................ 23
Choosing Axis Order.......................................................................................... 24
Negative Cell-Rank; Items ................................................................................. 24
Lists .................................................................................................................... 24
Phrases To Memorize ............................................................................................. 25
Constant Lists ......................................................................................................... 25
Array-creating Verbs .............................................................................................. 25
Dyad $ ($hape) and monad $ ($hape Of) .......................................................... 25
v
Monad # (Tally) ................................................................................................. 30
Monad i. (Integers) .......................................................................................... 30
6. Loopless Code I—Verbs Have Rank.......................................................................... 32
Examples of Implicit Loops.................................................................................... 32
The Concept of Verb Rank ..................................................................................... 34
Verb Execution—How Rank Is Used (Monads) .................................................... 34
Controlling Verb Execution By Specifying a Rank................................................ 36
Examples Of Verb Rank ......................................................................................... 37
fndisplay—A Utility for Understanding Evaluation ........................................ 40
Negative Verb Rank................................................................................................ 41
Verb Execution—How Rank Is Used (Dyads) ....................................................... 42
Concatenating Lists: Dyad , (Append).............................................................. 44
When Dyad Frames Differ: Operand Agreement ................................................... 45
Order of Execution in Implied Loops ..................................................................... 49
A Mistake To Avoid ............................................................................................... 49
7. Starting To Write In J ................................................................................................. 51
8. More Verbs ................................................................................................................. 54
Arithmetic Dyads.................................................................................................... 54
Boolean Dyads........................................................................................................ 55
Min and Max Dyads ............................................................................................... 55
Arithmetic Monads ................................................................................................. 55
Boolean Monad....................................................................................................... 55
Operations on Arrays .............................................................................................. 56
Dyads.................................................................................................................. 56
Monads ............................................................................................................... 62
9. Loopless Code II—Adverbs / and ~.......................................................................... 66
Modifiers................................................................................................................. 66
The Adverb Monad u/ ........................................................................................... 66
The adverb ~ ........................................................................................................... 68
10. Continuing to Write in J.............................................................................................. 70
11. Boxing (structures).................................................................................................... 76
Terminology............................................................................................................ 78
Boxing As an Equivalent For Structures In C ...................................................... 79
12. Compound Verbs ........................................................................................................ 80
Verb Sequences—u@:v and u@v .......................................................................... 80
The Difference Between u@:v and u@v ........................................................... 81
An Exercise in @ and @: .................................................................................... 82
Making a Monad Into a Dyad: The Verbs [ and ]................................................... 84
Making a Dyad Into a Monad: u&n and m&v......................................................... 85
13. Empty Operands.......................................................................................................... 87
Execution On a Cell Of Fills................................................................................... 87
Empty cells ............................................................................................................. 89
If Fill-Cells Are Not Enough .................................................................................. 89
14. Loopless Code III—Adverbs \ and \. ....................................................................... 90
15. Verbs for Arithmetic ................................................................................................... 93
Dyads ...................................................................................................................... 93
vi
Monads (all rank 0)................................................................................................. 94
16. Loopless Code IV ....................................................................................................... 95
A Few J Tricks........................................................................................................ 95
Power/If/DoWhile Conjunction u^:n and u^:v ................................................ 96
Tie and Agenda (switch) ........................................................................................ 99
The Tie Conjunction u`v u`n m`v m`n...................................................... 99
The Agenda (switch) conjunction m@.v ......................................................... 100
17. More Verbs For Boxes.............................................................................................. 101
Dyad ; (Link) And Monad ; (Raze).................................................................... 101
Dyad , Revisited—the Case of Dissimilar Items ............................................ 103
Verbs With More Than 2 Operands—Multiple Assignment ........................... 103
Dyad { Revisited: the Full Story .......................................................................... 104
Simplification 1: Remove Inner Boxing If Selectors Are Scalars.................... 106
Simplification 2: Remove All Boxing To Select Full Items ............................ 106
Split String Into J Words: Monad ;: ................................................................... 107
Fetch From Structure: Dyad {:: ......................................................................... 107
Report Boxing Level: Monad L. ......................................................................... 108
18. Verb-Definition Revisited......................................................................................... 110
What really happens during m :n and verb define ..................................... 110
Compound Verbs Can Be Assigned ..................................................................... 111
Dual-Valence verbs: u :v................................................................................... 112
The Suicide Verb [: ............................................................................................ 112
Multi-Line Comments Using 0 :0 ..................................................................... 113
Final Reminder ..................................................................................................... 113
19. u^:_1, u&.v, u&.:v, and u :.v ........................................................................ 114
The Obverse u^:_1............................................................................................. 114
Apply Under Transformation: u&.v and u&.:v ................................................ 114
Defined obverses: u :.v .................................................................................... 116
u&:v and u&v ................................................................................................... 116
An observation about dyadic verbs....................................................................... 117
20. Performance: Measurement & Tips .......................................................................... 118
Timing Individual Sentences ................................................................................ 118
Compounds Recognized by the Interpreter .......................................................... 120
Use Large Verb-Ranks! and Integrated Rank Support ......................................... 121
Shining a Light: The J Performance Monitor ....................................................... 122
21. Input And Output ...................................................................................................... 125
Foreigns ................................................................................................................ 125
File Operations 1!:n; Error Handling................................................................. 125
Error Handling: u ::v, 13!:11, and 9!:8................................................. 126
Treating a File as a Noun: Mapped Files.............................................................. 126
Format Data For Printing: Monad And Dyad ": ................................................. 127
Monad ": ......................................................................................................... 128
Format an Array: 8!:n ........................................................................................ 129
Format binary data: 3!:n .................................................................................... 130
printf, sprintf, and qprintf.................................................................... 131
vii
Convert Character To Numeric: Dyad ". ............................................................ 131
22. Calling a DLL Under Windows................................................................................ 133
Memory Management........................................................................................... 134
Filling a Structure: Conversions....................................................................... 135
Aliasing of Variables ............................................................................................ 135
Aliasing of Mapped Nouns............................................................................... 136
Aliasing of DLL Operands ............................................................................... 136
23. Socket Programming................................................................................................. 138
sdselect ........................................................................................................... 138
Asynchronous Sockets and socket_handler ................................................ 138
Names and IP Addresses....................................................................................... 139
Connecting ............................................................................................................ 140
Listening ............................................................................................................... 140
Other Socket Verbs............................................................................................... 141
Datagrams......................................................................................................... 141
Socket Options.................................................................................................. 141
Housekeeping ................................................................................................... 142
24. Loopless Code V—Partitions ................................................................................... 143
Find Unique Items: Monad ~. and Monad ~: .................................................... 143
Apply On Subsets: Dyad u/. .............................................................................. 143
Apply On Partitions: Monad u;.1 and u;.2..................................................... 145
Apply On Specified Partitions: Dyad u;.1 and u;.2 ...................................... 146
Find Sequence Of Items: Dyad E.................................................................... 147
Multidimensional Partitions ............................................................................. 148
Apply On Subarray: Dyad u;.0.......................................................................... 148
Apply On All Subarrays: Dyad u;.3 and u;._3 .............................................. 149
Extracting Variable-Length Fields Using ^: and ;.1 ........................................ 150
Example: Combining Adjacent Boxes.................................................................. 151
25. When Programs Are Data ......................................................................................... 153
Calling a Published Name..................................................................................... 153
Using the Argument To a Modifier ...................................................................... 153
Invoking a Gerund: m`:6..................................................................................... 154
Passing the Definition Of a Verb: 128!:2 (Apply)............................................ 155
Passing an Executable Sentence: Monad ". and 5!:5....................................... 156
26. Loopless Code VI ..................................................................................................... 157
27. Loopless Code VII—Sequential Machines............................................................... 161
28. Modifying an array: m}............................................................................................. 164
Monad I.—Indexes of the 1s in a Boolean Vector ............................................. 165
Modification In Place............................................................................................ 166
29. Control Structures ..................................................................................................... 167
for./do./end. and for_x./do./end.......................................................... 167
while./do./end. and whilst./do./end. ................................................. 167
if./do./else./end., if./do./elseif./do./end.................................. 167
try./catch./catcht./end. and throw. ................................................. 168
select./case./fcase./end. ...................................................................... 168
viii
return............................................................................................................... 169
assert............................................................................................................... 169
30. Modular Code ........................................................................................................... 170
Locales And Locatives.......................................................................................... 170
Assignment ........................................................................................................... 170
Name Lookup ....................................................................................................... 171
Changing The Current Locale............................................................................... 172
The Shared Locale 'z' ........................................................................................ 175
Using Locales ....................................................................................................... 175
31. Writing Your Own Modifiers ................................................................................... 177
Modifiers That Do Not Refer To x. Or y. ......................................................... 177
Example: Creating an Operating-System-Dependent Verb ............................. 178
Example: The LoopWithInitial Conjunction ........................................ 179
Example: A Conjunction that Analyzes u and v.............................................. 179
An Exception: Modifiers that Do Not Refer to u. or v. ................................ 181
Modifiers That Refer To x. Or y. ...................................................................... 181
32. Applied Mathematics in J ......................................................................................... 184
Complex Numbers ................................................................................................ 184
Matrix Operations ................................................................................................. 184
Polynomials: p..................................................................................................... 185
Calculus: d., D., D:, and p.. ............................................................................ 186
Taylor Series: t., t:, and T............................................................................... 187
Hypergeometric Function with H. ....................................................................... 187
Sparse Arrays: Monad and Dyad $. .................................................................... 188
Random Numbers: ?............................................................................................. 188
Computational Addons ......................................................................................... 189
Useful Scripts Supplied With J............................................................................. 189
33. Elementary Mathematics in J.................................................................................... 190
Verbs for Mathematics.......................................................................................... 190
Extended Integers, Rational Numbers, and x:..................................................... 190
Factors and Primes: Monad p:, Monad and Dyad q: ......................................... 191
Permutations: A. and C....................................................................................... 191
34. Graphics .................................................................................................................... 193
Plot Package.......................................................................................................... 193
Plot Demo......................................................................................................... 193
Interfaces to Plot............................................................................................... 193
Commands and Options ................................................................................... 194
Data; Constructing a Plot with pd.................................................................... 195
Quick Plots Using plot .................................................................................. 196
Generating Plots of Functions .......................................................................... 197
Assembling a Multipart Plot with pd............................................................... 198
Examples of Plots with Multiple Sets of Points ............................................... 199
Plots of Parametric Functions........................................................................... 199
Output Options ................................................................................................. 199
2D Graphics: the gl2 Library ................................................................................ 199
ix
Example of Drawing......................................................................................... 200
Creating an isigraph Graphics Control....................................................... 200
Selecting an isigraph Control for Output ................................................... 201
Addressing the Screen ...................................................................................... 201
Drawing Graphics............................................................................................. 201
Drawing Text.................................................................................................... 201
The Drawing Surface........................................................................................ 202
Screen Resizing: The paint Event................................................................. 202
Partial List of glxxx Drawing Commands ..................................................... 202
isigraph Events ........................................................................................... 205
High Performance: Blocks of glxxx Commands Using glcmds ................. 205
Displaying Tabular Data: the Grid Control .......................................................... 206
3D Graphics: OpenGL .......................................................................................... 206
35. Odds And Ends ......................................................................................................... 207
Dyad # Revisited .................................................................................................. 207
Boxed words to string: Monad ;:^:_1 .............................................................. 207
Spread: #^:_1 ..................................................................................................... 207
Choose From Lists Item-By-Item: monad m} ...................................................... 207
Recursion: $: ....................................................................................................... 208
Make a Table: Adverb dyad u/............................................................................ 208
Cartesian Product: Monad { ................................................................................. 209
Boolean Functions: Dyad m b. ........................................................................... 210
Functions on Boolean operands........................................................................ 210
Bitwise Boolean Operations on Integers .......................................................... 210
Operations Inside Boxes: u L: n, u S: n ...................................................... 211
Comparison Tolerance !.f.................................................................................. 213
Right Shift: Monad |.!.f .................................................................................. 213
Generalized Transpose: Dyad |: ......................................................................... 214
Monad i: and Dyad i: ....................................................................................... 214
Fast String Searching: s: (Symbols) ................................................................... 215
Fast Searching: m&i. ........................................................................................... 216
CRC Calculation ................................................................................................... 216
Unicode Characters: u:........................................................................................ 216
Window Driver And Form Editor......................................................................... 216
x
Referring To a Noun In a Tacit Verb.................................................................... 235
41. Readable Tacit Definitions ....................................................................................... 236
Flatten a Verb: Adverb f..................................................................................... 236
Using f. to improve performance ................................................................... 237
42. Explicit-To-Tacit Converter...................................................................................... 239
Special Verb-Forms Used in Tacit Definitions..................................................... 240
43. Common Mistakes .................................................................................................... 241
Mechanics ............................................................................................................. 241
Programming Errors ............................................................................................. 242
44. Valedictory................................................................................................................ 245
45. Glossary .................................................................................................................... 246
46. Error Messages.......................................................................................................... 250
47. Index ......................................................................................................................... 252
xi
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 array-
processing 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 array-
processing 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
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:
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.
4
Programming In J
5
3. Preliminaries
Terminology
To describe the elements of programming, J uses a vocabulary that will be familiar,
though possibly frightening: the vocabulary of English grammar. We will speak of
nouns, verbs, and the like. Don't worry, you're not going to have to write a book report!
Use of this terminology is not as strange as it may seem. Take 'verb', for example, an
idea that corresponds to the C 'function' or 'operator'. Why not just say 'operator'?
Well, that word is also used in mathematics and physics, with a meaning quite different
from C's. Even a C 'function' is not a true mathematical function—it can return different
values after invocations with the same arguments.
J avoids imprecise usage by choosing a familiar set of words and giving them entirely
new meanings. Since J is a language, the vocabulary chosen is that of English grammar.
It is hoped that the familiarity of the words will provide some mnemonic value, but as
long as you learn the J meanings you are free to forget the grammatical ones. The
following table may help:
J word C word
verb function or operator
noun object
copula assignment
punctuation separator
adverb (#define macro)
conjunction (#define macro)
In keeping with the grammatical flavor of the vocabulary, we say that every word
(token) in a J program has a part of speech (name type) which is one of the following:
noun, verb, adverb, adjective, copula, or punctuation.
The primary parts of speech are noun, verb, adverb, and conjunction. Every name
we can create, and every word defined by J except for the copulas (=. and =:) and
punctuation, will be a definite one of the primary parts of speech. In this book, the term
entity is used to mean something that can be any of the primary parts of speech. An
6
entity can be assigned to a name, but most entities are anonymous, appearing and
disappearing during the execution of a single sentence (just like intermediate results in
the evaluation of C expressions).
A noun holds data; a verb operates on one or two nouns to produce a result which is a
noun; an adverb operates on one noun or verb to produce a derived entity; a conjunction
operates on two nouns or verbs to produce a derived entity. Adverbs and conjunctions
are called modifiers. The closest thing C has to a modifier is a preprocessor macro which
can accept function names as data and produce code sequences including the name. J
modifiers perform their actions during execution rather than compilation, providing
opportunities unknown to C.
A word on punctuation under J's definition: it consists of the characters ( ) ' and
end-of-line (written LF but representing either a single LF character or the CRLF
combination), along with the comment delimiter NB. and a few other special words like
if. and case. . There are a lot of other characters that you think of as punctuation,
namely [ ] , . " ; { }, that J uses to do work. You will be especially surprised
to find that [ ] and { } are independent rather than matched pairs, but you'll get used
to it.
Sentences (statements)
The executable unit in J is called the sentence, corresponding to the C statement.
The sentence delimiters in J (corresponding to the semicolon in C) are the linefeed LF
and the control words like if. that we will learn about later. A sentence comprises all
the characters between sentence delimiters; since LF is a sentence delimiter, it follows
that a J sentence must all fit on one line. There is nothing corresponding to \<CR> in C
that allows you to split a sentence across lines.
All comments start with NB. and run to the next LF . The comment is ignored when
the sentence is executed.
7
+ +. +: { {: {:: i. i: for. select. case. end.
The first step in processing a sentence is to split it into words. The words correspond
roughly to C tokens, after making allowance for the special status of the '.' and ':'
characters. The space and TAB characters are treated as whitespace.
We will be careful to distinguish periods used for English punctuation from the dot
that may be at the end of a primitive. When a J word comes at the end of an English
sentence, we will be sure to leave a space before the period. For example, the verb for
Boolean Or is +., while the verb for addition is + .
Numbers
You do not need to trouble yourself with the distinction between integers, floats, and
complex numbers. If it's a number, J will handle it properly. There are a great many
ways to specify numbers; consult the Dictionary to learn details, including, among other
things, complex numbers, extended-precision integers, and exponential forms. Example
numbers are:
2
_2 (underscore, not -, is the negative sign)
0.5 (since '.' is special, it must not be the first character of a number)
1e2
16b1f (equivalent to 0x1f)
_ (infinity, which is a perfectly valid number in J)
__ (negative infinity, represented by two underscores)
A noun whose value is one of the numbers 0 and 1 is said to be Boolean. Many verbs
in J are designed to use or produce Boolean values, with 0 meaning false and 1 meaning
true, but there is no Boolean data type: any noun can be used as a Boolean if its values
are 0 or 1.
A word is in order in defense of the underscore as the negative sign. -x means 'take
the negative of the number x'; likewise -5 means 'take the negative of the number 5'. In
J, the number 'negative 5' is no cloistered companion, accessible only by reference to the
number 5: it is a number in its own right and it deserves its own symbol: _5.
Adjacent Numbers Form a Single Word
Numbers separated by whitespace are treated as a single word whose value is the list
of the numbers (we will learn all about lists soon—they're like arrays). Remember,
word formation is the first step in processing a sentence, so the numbers are welded into a
list before anything else can be done with them. This may cause you a problem if you
have adjacent numbers that should not be made into a list. In that case, put parentheses
around any number you want to keep separate.
You will quickly learn that lists of numbers are so common in J that creating them
automatically from adjacent numbers saves you a lot of typing.
8
Adjacent Named Nouns Do NOT Form a Single Word
Because the adjacent numbers 4 5 are turned into a list, you might think that a b,
when a and b have the values 4 and 5, would also be turned into a list. Not so. 4 5
becomes a list before any of the names are examined; at that point the interpreter does not
even know the part of speech of the names. a and b remain as separate words, to be
operated on as execution proceeds.
Characters
An ASCII string enclosed in single quotes is a constant of character type (examples:
'a', 'abc'). There is no notation to make the distinction between C's single-quoted
character constants and double-quoted character strings.
There are no special escape sequences such as '\n'. If you need a quote character
inside a string, double the quote: 'cannot can be shortened to can''t'.
Character constants do not include a trailing NUL (\0) character, and NUL is a legal
character within a string.
9
How Names (Identifiers) Get Assigned
Assignment in J is performed by expressions of the form
name =. entity NB. private
and
name =: entity NB. public
Names assigned by public assignment are visible outside the entity in which they are
defined; names assigned by private assignment usually are not; we will learn the details
when we discuss modular code. The difference between the two forms of assignment is
in the character following the = . Just as in C, the assignment expression is considered
to produce as its result the value that was assigned, so expressions like
a =. 1 + b =. 5
are legal. J calls =. and =: copulas. Just as in C, the entity that is assigned to the name
can be the result of evaluating an expression.
There are a number of additional capabilities of J assignment that you can read about
in the Dictionary. One that has no counterpart in C is that the name being assigned can
itself be a variable, i. e. you can calculate the name that you want to assign the value to.
The value assigned can be a noun (object), verb (function), adverb, or conjunction;
the name then becomes whatever part of speech was assigned to it (even if it was
previously defined as a different part of speech!). For example,
n =: 5
creates a noun, and
v =: verb define
x. + y.
)
creates a verb (more below).
Note: the J Dictionary uses the terms 'local' and 'global' instead of 'private' and
'public'. I think 'private' and 'public' are more accurate terms, because there is another
dimension to name scope in J, using the J notions locale and path, that causes public
variables to be visible only in certain entities. It will be a long time before we learn about
locales; until then, public names will be global.
Order of Evaluation
Forget the table of operator precedence! All J verbs (functions and operators)
have the same priority and associate right-to-left. For example, a * b + c is
equivalent to a * (b + c), not (a * b) + c. Use care when copying
mathematical formulas. Note that the negative sign _ is a part of the number, not a verb.
_5 + _4 is _9, while -5 + -4 is _1.
The executable bits of a sentence (statement) are called fragments
(subexpressions). A verb with its operand(s) is a fragment, as is a copula with its
name and value. We will meet other types of fragment later. Execution of a sentence
consists of the right-to-left execution of its fragments, with the result of each fragment's
execution replacing the fragment and being passed as an operand into the next fragment.
The result of the last execution becomes the result of the sentence. This result is usually
10
a noun but it can be any of the primary parts of speech. As an example, execution of the
sentence
a =. 3 + b =. 4 * 5
consists of execution of the following fragments: 4 * 5 with result 20; b =. 20 with
result 20; 3 + 20 with result 23; a =. 23 with result 23 . The names a and b are
assigned when the assignment fragments are executed.
If a verb has a noun on its left, it is executed as a dyadic verb with a left and right
operand. If the verb does not have a noun on its left, it is executed as monadic with just a
right operand. You must know the part of speech of the names in a sentence to
understand the execution order. In the sentence
result =. name1 verb2 5
you must know name1 is a verb, in which case verb2 is executed monadically and the
result is name1(verb2(5)), or name1 is a noun, in which case verb2 is dyadic and
the result is (name1 verb2 5) .
11
4 5
and
a b
when a is 4 and b is 5 . 4 5 is two adjacent numbers, which are always treated as a
single word. a b is equivalent to (4) (5), which is not two adjacent numbers but
rather a syntax error.
12
name =: monad : 'text of verb'
name =: dyad : 'text of verb'
Running a J program
No compiling. No linking. No makefiles. No debugger. You simply type J
sentences and the interpreter executes them and displays any result. At the very simplest,
you can use it as a desk calculator:
22 + 55
77
J prints 3 spaces as a prompt, so when you scroll through the log of a session, your
input will be indented 3 spaces while J's typeout will be unindented. The result of a
sentence typed on the keyboard is displayed, except that to avoid excessive typeout
nothing is displayed if the last fragment executed in the sentence is an assignment. If you
are at the keyboard while you are reading this book, you can type the examples and see
the responses, or experiment on your own.
Here is a simple program to add twice the left argument to three times the right
argument:
add2x3y =: dyad : '(2 * x.) + 3 * y.'
We can run this program by giving it operands:
1 2 3 add2x3y 4 5 6
14 19 24
Instead of simply displaying the result, we can assign it to a noun:
a =: 1 2 3 add2x3y 4 5 6
We can inspect the value assigned to the noun by typing the name of the noun:
a
14 19 24
We can use the noun in an expression:
2 * a
28 38 48
We can create a new verb that operates on the noun:
twicea =: monad : '2 * a'
twicea ''
28 38 48
Notice the '' after the invocation of twicea. Remember, to invoke a verb you must
give it an operand, even if the verb doesn't use an operand. '' is just an empty string; 0
or any other value would work too. If you leave out the operand, J will show you the
value of the name; since twicea is a verb, its value is the definition of the verb:
twicea
3 : '2*a'
Of course, in any practical application you will need to have most of your programs
in a library so you can quickly make them all available to J. J calls these libraries scripts
(filename extension '.ijs') and runs them with the load verb, for example:
13
load 'system\packages\misc\jforc.ijs'
load reads lines from the script and executes them. These lines will normally be all
the verb and noun definitions your application needs, possibly including load
commands for other scripts. A script may end with a line executing one of the verbs it
defined, thereby launching the application; or, it may end after defining names, leaving
you in control at the keyboard to type sentences for J to execute.
Note: Names defined by private assignment (using =.) when
a script is loaded are not available outside the script. If you
want to define names for use elsewhere, make sure you use
=: for your assignments within a script.
If you are used to debugging with Visual C++™ or the like, you will find the
environment less glitzy and more friendly. If you want to change a verb (function), you
simply edit the script, using the editor of your choice (I use the built-in editor provided
with J), and rerun it. The verb will be updated, but all defined nouns (objects) will be
unchanged. Even if you are running a large application—yea, even if the application is in
the middle of reading from an asynchronous socket—you can change the program,
without recompiling, relinking, or reinitializing. If you'd like to add some debugging
code while the system is running, go right ahead. This easy interaction with an executing
program is one of the great benefits of programming in J.
Interrupting Execution
If a J verb is taking too long to run, signal it to stop by running the Jbreak program
that is supplied as part of the J installation. Control will return to the keyboard.
Errors
When a sentence contains an error, J stops and displays the sentence along with a
terse error message. Refer to the chapter on Error Messages for explanation of the error.
14
Sentences that you type into a script window are not automatically executed by J; you
must copy them into the execution window to have them executed. You can use the
script-window editor to send lines from a script to the execution window: click Run on
the Menu Bar and then File, Selection, or Window as appropriate.
To run a selection of lines from a script window, be sure to
use Run|Selection rather than cut-and-paste. If you paste a
number of lines into the execution window, only the last one
will be executed.
It is important to remember that the script windows exist only for your convenience in
editing and are not used during execution. If you make a change to a script window, you
need to Run that window to cause the lines in the script to be executed.
If you are debugging a script and you remove a definition from the script and Run it,
the definition will not be removed from the J session. Running the script is like entering
the sentences one by one from the keyboard, and not-defining the name does nothing to
expunge an established definition. To remove the old definition, use
4!:55 <'expiredname' or start a fresh session of J.
15
J Documentation
The J documentation is available online. Pressing F1 brings up the Vocabulary page,
from which you can quickly go to the Dictionary's description of each J primitive. At the
top of each page of documentation are links to the manuals distributed with J: these are:
The Index to all documentation;
The User Manual which describes components of J that are not in the language itself,
including system libraries and external interfaces;
The J Primer, an introduction to J;
J Phrases, a collection of useful fragments of J (you will need to finish this book
before trying to use J Phrases);
The J Dictionary, the official definition of the language;
Release Notes for all releases of J;
A description of foreign conjunctions (!:);
A description of the operands to the wd verb (Windows interface).
Getting Help
Your first step in learning J should be to sign up for the J Forum at
www.jsoftware.com. A great many experienced J users monitor messages sent to the
Forum and are willing to answer your questions on J, from the trivial to the profound.
16
4. A First Look At J Programs
Before we get into learning the details of J, let's look at a couple of realistic, if simple,
problems, comparing solutions in C to solutions in J. The J code will be utterly
incomprehensible to you, but we will nevertheless be able to see some of the differences
between J programs and C programs. If you stick with me through this book, you will be
able to come back at the end and understand the J code presented here.
17
fid = fopen(acctfn);
for(nacct = 0;2 == fscanf(fid,"%f%f",acctno,openbal) {
acct[nacct].ano = acctno;
acct[nacct].openbal = openbal;
acct[nacct].prevday = 1;
acct[nacct].currbal = openbal;
acct[nacct].weightbal = 0;
++nacct;
}
fclose(acctfn);
// Process the journal: for each record, look up the account
// structure; add closing-balance values for any days that
// ended before this journal record; update the balance
fid = fopen(jourfn);
while(3 == fscanf(fid,"%f%f%f",acctno,xactnday,xactnamt) {
for(acctx = 0;acct[acctx].ano != acctno;++acctx);
acct[nacct].weightbal +=
acct[nacct].currbal * (xactnday - acct[nacct].prevday);
acct[nacct].currbal += xactnamt;
acct[nacct].prevday = xactnday;
}
18
NB. Verb to convert TAB-delimited file into numeric array
rdtabfile =: (0&".;.2@:(TAB&,)@:}:);._2) @ ReadFile @<
NB. Verb to process journal and account files
NB. y. is (# days in current month);(Account filename);
NB. (Journal filename)
acctprocess =: monad define
'ndays acctfn jourfn' =: y.
NB. Read files
'acctano openbal' =. |: rdtabfile acctfn
'jourano jourday jouramt' =. |: rdtabfile jourfn
NB. Verb: given list of days y., return # days that
NB. each balance is a day's closing balance
wt =. monad : '(-~ 1&(|.!.(>:ndays))) 0{"1 y.'
NB. Verb: given an Account entry followed by the Journal
NB. entries for the account, produce (closing balance),
NB. (average daily balance)
ab =. monad : '(wt y.)({:@] , (%&ndays)@(+/)@:*)+/\1{"1 y.'
NB. Create (closing balance),(average daily balance) for
NB. each account. Assign the start-of-month day (1) to the
NB. opening balance
cavg =. (acctano,jourano) ab/.(1,.openbal),jourday,.jouramt
NB. Format and print all results
s =. 'Account %d: Opening %d, closing %d, avg %d\n'
s&printf"1 acctano ,. openbal ,. cavg
''
)
Let's compare the two versions. The first thing we notice is that the J code is mostly
commentary (beginning with NB.). The actual processing is done in 3 lines that read the
files, 3 lines to perform the computation of closing and average balance, and 2 lines to
print the results. J expresses the algorithm much more briefly.
The next thing we notice is that there seems to be nothing in the J code that is looping
over the journal records and the accounts. The commentary says 'create balances for each
account' and 'produce average daily balance for an account', tasks that clearly require
loops, and yet there is nothing resembling loop indexes. This is one of the miracles of J:
loops are implied; in C terminology, they are expressions rather than statements,
and so they can be assembled easily into single lines of code that replace many nested
loops. We will be spending a lot of time learning how to do this.
We also note that there is nothing in the J code corresponding to the
#define MAXACCT 500 in the C. This is one of the things that makes programming in
J so pleasant: you don't have to worry about allocating storage, or freeing it, or wondering
how long is long enough for a character-string variable, or how big to make an array.
Here, even though we don't know how many accounts there are until we have read the
entire Accounts file, we simply read the file, split it into lines and numbers, and let the
interpreter allocate as much storage as it needs to hold the resulting array.
19
The last thing to see, and perhaps the most important, is that the C version is just a toy
program. It searches through the Accounts information for every record in the Journal
file. We can test it with a small dataset and verify that it works, but if we scale it up to
10,000 accounts and 1,000,000 journal entries, we are going to be disappointed in the
performance, because its execution time will be proportional to A*J where A is the
number of accounts and J the number of journal entries. It is every programmer's dread:
a function that will have to be rewritten when the going gets tough.
The J version, in contrast, will have execution time proportional to (A+J)*log(A+J).
We did nothing meritorious to achieve this better behavior; we simply expressed our
desired result and let the interpreter pick an implementation. Because we 'think big'—we
treat the entire Journal and Accounts files as units—we give the interpreter great latitude
in picking a good algorithm. In many cases the interpreter makes better decisions than
we could hope to, because it looks at the characteristics of the data before it decides on its
algorithm. For example, when we sort an array, the interpreter will use a very fast
method if the range of numbers to be sorted is fairly small, where 'fairly small' depends
on the number of items to be sorted. The interpreter takes great care in its
implementation of its primitives, greater care than we can normally afford in our own C
coding. In our example, it will use a high-speed method for matching journal entries with
accounts.
20
// Program to calculate Chebyshev coefficients
// Code taken from Numerical Recipes in C 1/e
#include <math.h>
#define PI 3.141592653589793
void chebft(a,b,c,n,func)
float a,b,c[ ];
float (*func)();
int n;
{
int k,j;
float fac,bpa,bma,f[300];
21
5. Declarations
J has no declarations. Good riddance! No more will you have to warn the computer
of all the names you intend to use, and their types and sizes. No more will your program
crash if you step outside an array bound. You specify the calculations you want to
perform; if, along the way, you want to assign a result to a name, J will allocate enough
space for the data. It will free the space when the name is no longer needed.
Seasoned C programmers have learned to use declarations to create a web of type-
checking, making sure that objects pointed to are of the expected type. This is an
example of making a virtue of necessity. Since J solves the problem much more
directly—by not having pointers at all—you will soon lose your uneasiness with weak
typing.
Arrays
But, you ask, without declarations, how does the computer know that a name
represents an array? For that matter, how do I know that a name represents an array?
The answer affords a first glimpse of the power of J. Every J verb, whether a
primitive (operator) or a user-written verb (function), accepts arguments that can be
arrays, even multidimensional arrays. How is this possible? Like this: Suppose you
write a verb that works with 2-dimensional arrays. Part of your verb definition will
indicate that fact. If your verb is executed with an argument that is a 3-dimensional
array, J will automatically split the 3-dimensional array into a sequence of 2-dimensional
arrays, call your verb, and put the pieces back together into an array of results.
We will very soon go into this procedure in great detail. For now, you should learn
the vocabulary J uses to deal with arrays.
What C calls an n-dimensional array of rank i×j×…×k is in J an array of rank n
with axes of length i,j,…,k.
Every noun (variable or object) has a shape which is the array (of rank 1) made by
concatenating the lengths of all its axes. For example, if q is the array corresponding to
the C array defined by the declaration
int q[4][5][6];
its shape is the array 4 5 6 . As you can see, the number of items in the shape is
exactly the rank.
Note: a sequence of numbers written with no intervening
punctuation defines a numeric array of rank 1 (i. e. a list).
You may have to use parentheses if you have adjacent
numbers that you don't want to have made into a list.
Unlike in C, an array in J may have one or more axes of length 0. Such an array has
no atoms, but its rank is still the number of its axes.
22
A single number or character is called an atom (object of basic type) which is said
to have the type numeric or character as appropriate. (Actually, there are types other than
number and character, including a type that resembles a structure, but we won't get to
them for a while). An atom is also called a scalar. An atom is defined to have rank 0;
therefore, its shape is an array with 0 items, i. e. an empty array of rank 1.
Just as in C, every atom of an array must have the same type.
Cells
Because the execution of every J verb involves breaking the argument into pieces,
presenting the pieces to the verb, and assembling results, J has a vocabulary for
describing these operations.
A rank-3 array of shape 4 5, 6 such as the one defined in C by the declaration
int q[4][5][6];
can be thought of as an array of 4 elements, each with rank 2 and shape 5 6, or as a 4×5
array of elements, each with rank 1 and shape 6, or as a 4×5×6 array of rank-0 atoms.
The term cell is used to indicate the rank of the elements that will be operated on. A
0-cell is an atom, a 1-cell is an element of rank 1, a 2-cell is an element of rank 2, and so
on.
Once you have picked a cell size, you can think of your noun as an array of cells; the
shape of that array is called the frame of the noun relative to the chosen rank of cell. It
follows that the frame, concatenated with the shape of the cells, will be equal to the shape
of the noun. The frame itself (like all shapes) is an array of rank 1.
The diagram illustrates cells of different ranks. Note that the twenty 6-atom 1-cells
are arranged in a 4×5 array; this is the meaning of the frame of the 1-cells. The four 5×6
2-cells are arranged as a vector of 2-cells; this is the meaning of their frame.
A selected cell is analogous to the subarray selected by indexing in C. Using q as
defined above, in C q[3] is a 5×6 array (i. e. a 2-cell); q[1][0] is a 6-element vector (i. e.
a 1-cell); q[2][0][3] is a scalar (0-cell).
The noun q we have been using as an example can be thought of in any of the
following 4 ways:
23
Frame Cells
as an array of Length Value Rank Shape
0-cells 3 4 5 6 0 (empty)
1-cells 2 4 5 1 6
2-cells 1 4 2 5 6
3-cells 0 (empty) 3 4 5 6
24
When the word 'list' is used without any indication of what the list contains, the list is
assumed to contain atoms. So, 'the list x' refers to an array of rank 1 (one-dimensional
array). 0 3 5 is a numeric list.
Note that J's use of the term 'list' has nothing to do with linked lists such as you are
familiar with, where an element in the list contains a pointer to other elements. Since J
has no pointers at all, you will not need that meaning, and you can get used to calling
rank-1 arrays 'lists'. A list can also be called a vector.
Phrases To Memorize
An array is a list of its items.
An atom has one item, itself.
The rank of a noun is the length of its shape.
The shape of an atom is the empty list.
The suffixes of the shape of a noun give the shapes of its cells: the k trailing atoms of
the shape of a noun give the shape of its k-cell.
The frame of a noun with respect to k-cells is the shape of the noun, with the last k
atoms of the shape removed.
Constant Lists
A character or numeric list can be created simply by including the list in a sentence.
We have seen that a sequence of numbers separated by spaces is recognized as a single
word representing the list. Similarly, a character or a character list can be represented
directly by a quoted string. C distinguishes between single-character constants (such as
'a') and strings (such as "abc"), using single quotes for characters and double quotes for
strings. J uses only single quotes for defining character constants (the " character is a
primitive in its own right). If exactly one character is between the quotes, the value is an
atom; if none or more than one, the result is a list.
Array-creating Verbs
Now that we know how to talk about arrays, we might as well create a few and see
what they look like. As mentioned earlier, every J verb can be used to create an array—
there are no special 'declaration' verbs—but we will start with a couple that do little else.
The J lines are taken from an interpreter session; you can type them into your own
session and get the same results. The indented lines were typed into J, and the
unindented ones are J's responses.
Dyad $ ($hape) and monad $ ($hape Of)
The verb dyad $ is invoked as x $ y . The result of dyad $ has the frame x
relative to the rank of the items of y, and is made up of the items of y, repeated cyclically
as needed. It follows that the shape of this result is x concatenated with the shape of an
item of y .
25
We will have to work together on this. Confronted with a definition like that, you
might: (a) decide that J must be a language for tax accountants, and give up; (b) decide
the definition is Greek and go on, hoping it will make sense later; (c) try a few examples
to get an idea for what the definition means; (d) read it over and over again until you
understand it. I hope you will eschew (a) and (b), and settle for no less than full
understanding. For my part, I will offer a few useful examples that you can compare
against the definition. Not everything in J will be as abstract as this.
5 $ 2
2 2 2 2 2
The simplest case, creating (and displaying) a list of 5 items, each of which is 2 . Let's
see how this result matches the definition. y is a scalar, so it has one item, which is also
a scalar. Therefore, the result has the shape 5 (x (i. e. 5) concatenated with the shape of
an item of y; the shape of a scalar item of y is the empty list; 5 concatenated with an
empty list is a list with the single element 5). The scalar is repeated to fill the 5 items of
the result. J displays a 1-cell on a single line, as shown.
5 $ 'ab'
ababa
Now y is a list, but its items are still scalars, with rank 0 and shape empty; so the result
still has the shape 5 . The 5 items come from the items of y, cyclically.
We can distill the foregoing analysis above to the observation that when y is an atom
or a list, x specifies the shape of x $ y .
4 4 $ 'There is a tide in the affairs of men'
Ther
e is
a t
ide
The items of y are still scalars, with rank 0 and shape empty; the result has the shape
4 4 . The 16 items come from the items of y, cyclically. Not all items of y are used. J
displays a rank-2 array as a sequence of lines, one for each 1-cell.
0 $ 2
(The display is a single blank line) Just like 5 $ 2, but the resulting list has 0 items,
i. e. it is an empty list.
1 $ 2
2
Similarly, a 1-item list.
(0 $ 2) $ 2
2
Here (0 $ 2) produces an empty list, as we saw above, and that is the x to the second
$ . The items of y are still scalars, so the result has shape empty (an empty list
concatenated with an empty list), i. e. it is a scalar.
The displays of a scalar and a 1-item list are identical. Does that mean that a scalar is
the same thing as a 1-item list? No. I mean no. NO! They are not (I say this with the
26
same resignation as when I tell my kids not to rollerblade too fast down our street,
knowing that only painful experience will drive the message home). How can you tell
them apart? What we need is a way to see the shape of a noun.
That way is monad $ . The result of $ y is the shape of y (always a numeric list).
For example:
$ 1 2 3 4
4
A 4-item list has the shape 4 . Did you forget that 1 2 3 4 is a single list rather than 4
separate numbers? You can ask the interpreter how it splits a line into words by using
monad ;: :
;: '$ 1 2 3 4'
+-+-------+
|$|1 2 3 4|
+-+-------+
The words are shown in boxes. The list 1 2 3 4 is recognized as a single word.
$ 6
The shape of a scalar is a 0-length list, as we have seen.
$ 1 $ 2
1
Remember, all sentences are executed right-to-left, so this is $ (1 $ 2), which gives
the shape of the 1-item list. When a verb can be invoked dyadically, it is, so the
rightmost $ is executed as a dyad, not as a monad.
$ (0 $ 2) $ 2
Here, we get the shape of the scalar—an empty list.
$ 'a'
A single character is an atom, whose shape is the empty list.
$'abc'
3
A 3-item list, one item for each character.
$ ''
0
'' is the empty character string, which you will see a lot of. Because it is easy to type, it
is the value most often used when an empty list of any type will do.
Executing monad $ twice gives the rank: $ $ y is the rank of y (as a single-item
list). I suggest you not read on until you understand why.
Resuming our inquiries into dyad $, we have
2 5 $ 1 10
1 10 1 10 1
10 1 10 1 10
Again y is a list, so the items of y are scalars. The shape of the result is 2 5, and the
items of y are repeated to fill that shape. Note that the corresponding atoms in each cell
are aligned in the display.
27
1 5 $ 1 10
1 10 1 10 1
Similarly, but now the result has shape 1 5. This is not the same as a 5-item list, which
has shape 5 . Again, monad $ shows the shape:
$ 1 5 $ 1 10
1 5
When y is not a scalar or a list, its items are not scalars, and x does not give the shape
of the result. Let us work through an example using the definition of x $ y :
3 $ 1 5 $ 1 10
1 10 1 10 1
1 10 1 10 1
1 10 1 10 1
Remember, this is processed as 3 $ (1 5 $ 1 10). The parenthesized part
produces an array of shape 1 5; since this has rank 2, its items are its 1-cells, each with
shape 5. The shape of the overall result is x concatenated with the shape of an item of y,
to wit 3 5. This is populated with the cells of y, of which there is only 1.
3 $ 2 5 $ 'There is a tide in the affairs of men'
There
is a
There
You should be able to explain where each line came from, and you should note that in
general, x specifies the frame of x $ y with respect to items of y . When y is a list
or an atom, its items are atoms and x gives the entire shape of the result.
2 2 $ 2 5 $ 1 10
1 10 1 10 1
10 1 10 1 10
1 10 1 10 1
10 1 10 1 10
$ 2 2 $ 2 5 $ 1 10
2 2 5
Now the shape of the result is 2 2 5, a rank-3 array. J displays the 2-cells with a blank
line in between. Similarly, a rank-4 array is displayed as all the 3-cells with 2 blank lines
in between, and so on for higher ranks.
We have seen that the display of a zero-length list is a single blank line: proper, as
there is one list, and it has no items. The display of a rank-2 array with no items is
different: here we have zero lists, so we should expect no lines at all. This is indeed what
happens:
0 0$0
(there is no blank line). This is the result you should produce if you want a function to
display nothing.
Here are two exercises. Once you can explain each result, you will be well on your
way to becoming a J programmer. What will each of these sentences produce (answer on
the next page)?
28
3 1 $ 2 5 $ 1 10
2 3 $ 2 5 $ 1 10 15
29
Solutions:
3 1 $ 2 5 $ 1 10
1 10 1 10 1
10 1 10 1 10
1 10 1 10 1
2 3 $ 2 5 $ 1 10 15
1 10 15 1 10
15 1 10 15 1
1 10 15 1 10
15 1 10 15 1
1 10 15 1 10
15 1 10 15 1
Monad # (Tally)
The result of # y is a scalar, the number of items in y . This is the first item in the
list $y, except that if y is an atom, $y is empty but #y is 1 (because, remember, an atom
has one item, itself). If y is a list, #y is the length of the list. Quiz question: What is the
difference between the results of $ 1 2 3 and # 1 2 3?
$ 1 2 3
3
# 1 2 3
3
Answer: the result of monad $ is always a list, but the result of monad # is a scalar:
$ $ 1 2 3
1
$ # 1 2 3
#$y, like $$y, gives the rank of y . Since monad # produces a scalar rather than a
list, #$y is usually preferred. Just remember that the length of the shape is the rank.
Monad i. (Integers)
Monad i. accepts a scalar or vector operand and creates an array. i. y produces
the same result as y $ ints, where ints is the list of all nonnegative integers in
order. Examples:
i. 5
0 1 2 3 4
A list of 5 items; the items are ascending integers.
i. 2 3
0 1 2
3 4 5
A rank-2 result.
30
i. 2 3 4
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
16 17 18 19
20 21 22 23
A rank-3 result.
i. 0
A list of 0 items.
i. _5
4 3 2 1 0
If the argument is negative, the absolute value is used for the shape, but the items run in
reverse order.
31
6. Loopless Code I—Verbs Have Rank
Most J programs contain no loops equivalent to while and for in C. J does contain
while. and for. constructs, but they carry a performance penalty and are a wise
choice only when the body of the loop is a time-consuming operation. You are just going
to have to learn to learn to code without loops.
I think this is the most intimidating thing about learning J—more intimidating even
than programs that look like a three-year-old with a particular fondness for periods and
colons was set before the keyboard. You have developed a solid understanding of loops,
and can hardly think of programming without using them. But J is a revolutionary
language, and all that is solid melts into air: you will find that most of your loops
disappear altogether, and the rest are replaced by small gestures to the interpreter
indicating your intentions.
Come, let us see how it can be done. I promise, if you code in J for 6 months, you
will no longer think in loops, and if you stay with it for 2 years, you will see that looping
code was an artifact of early programming languages, ready to be displayed in museums
along with vacuum tubes, delay lines, and punched cards. Remember, in the 1960s
programmers laughed at the idea of programming without gotos!
You are not used to classifying loops according to their function, but I am going to do
so as a way of introducting J's primitives. We will treat the subject of loopless iteration in
6 scattered chapters, showing how to replace different variants of loops:
1. Loops where each iteration of the loop performs the same operation on different
data;
2. Loops that apply an operation between all the items of the array, for example
finding the largest item;
3. Loops where the operation to be performed on each cell is different;
4. Loops that are applied to regularly-defined subsets of the data;
5. Loops that are applied to subsets of the data defined irregularly;
6. Loops that accumulate information between iterations of the loop;
7. Loops that implement finite-state machines.
The simplest case is the most important, and we start with a few experiments.
32
1 2 3 + 4 5 6
5 7 9
And look! If each operand is a list, the respective items are added. We wonder if the
behavior of 2 + 3 4 5 was because items of the shorter operand are repeated
cyclically:
1 2 + 4 5 6
|length error
| 1 2 +4 5 6
Evidently not. A 'length error' means that the operands to + did not 'agree' (and you get
an error if you try to add them). We will shortly understand exactly what this means.
i. 2 3
0 1 2
3 4 5
A reminder of what monad i. does.
0 100 + i. 2 3
0 1 2
103 104 105
Whoa! The atoms of the left operand were applied to rows of the right operand.
Interesting. This seems to be some kind of nested implicit loop.
Let's learn a couple of more verbs, monad #. and monad #: . Monad #: creates the
binary representation of an integer (i. e. a list of 0s and 1s), and monad #. is its inverse,
creating the integer from the binary representation. For the longest time I couldn't
remember which was which, but at last I saw the mnemonic: the verb with the single dot
(#.) creates an atom from a list; the verb with multiple dots (#:) creates a list from an
atom:
#: 5
1 0 1
#. 1 0 1
5
Yes, they seem to perform as advertised. They can be applied to arrays:
]a =. #: 5 9
0 1 0 1
1 0 0 1
Look: the result is not a rank-1 list, but rather a rank-2 array, where each item has the
binary representation of one operand value (and notice, an extra leading zero was added
to the representation of 5). The little trick with ]a =. will be explained later, but for
now just think of ]a =. as 'assign to a and display the result'. With a assigned, we
have:
#. a
5 9
This seems to be the desired result, but on reflection we are puzzled: how did the
interpreter know to apply #. to each 1-cell rather than to each 0-cell? Contrast this result
with the result of the verb monad +:, which means 'multiply by 2':
33
+: a
0 2 0 2
2 0 0 2
Evidently the verbs themselves have some attribute that affects the rank of cell they are
applied to. It's time for us to stop experimenting and learn what that attribute is.
34
Obviously, this will yield an array of shape f whose items have the shape of the
result of applying the verb to an r-cell.
Let's look at some simple examples:
i. 2 2
0 1
2 3
This will be the right operand.
+: i. 2 2
0 2
4 6
The steps to get this result are:
The verb rank is 0 and the noun rank is 2, so we will be
applying the verb to 0-cells. The frame f is 2 2
0 2
The verb is applied to each cell:
4 6
Another example:
]a =. 2 2 4 $ 0 0 1 1 0 0 0 1 0 1 0 0 0 0 1 0
0 0 1 1
0 0 0 1
0 1 0 0
0 0 1 0
This is a rank-3 array.
35
#. a
3 1
4 2
The verb rank is 1 and the noun rank is 3, so we will be applying the
verb to 1-cells. The frame f is 2 2
3 1
The verb is applied to each cell:
4 2
36
for(i = 0;i<2;++i) {
sum[i] = 0;
for(j = 0;j<3;++j)sum[i] += array[i][j];
}
to produce the result 3 12? How can we do it in J? What we have learned so far is not
enough, but if we had a way to make monad +/ apply to 1-cells—if we could make
monad +/ have rank 1—our problem would be solved: the implicit looping would cause
each row to be summed and the results collected.
You will not be surprised to learn that J does indeed provide a way to apply monad
+/ on 1-cells. That way is the rank conjunction " .
We will learn all about conjunctions later on—the syntax is a little different than for
verbs—but for now, we'll try to understand this " . It's used like this:
u"n
to produce a new verb that is u applied to n-cells individually. This is a simple idea,
but its ramifications spread wide. As a first example:
+/"1 i. 2 3
3 12
This is what we were looking for. It happened this way:
37
i. 2 3 4
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
16 17 18 19
20 21 22 23
+/"1 i. 2 3 4
6 22 38
54 70 86
The verb rank is 1 and the noun rank is 3, so we will be applying the
verb to 1-cells. The frame f is 2 3
38
+/"2 i. 2 3 4
12 15 18 21
48 51 54 57
The verb rank is 2 and the noun rank is 3, so we will be applying the
verb to 2-cells. The frame f is 2
0123 12 13 14 15
Think of the operand
4567 16 17 18 19
as a list of 2 2-cells:
8 9 10 11 20 21 22 23
39
Other documents randomly have
different content
The Project Gutenberg eBook of Mademoiselle
de Bressier
This ebook is for the use of anyone anywhere in the United
States and most other parts of the world at no cost and with
almost no restrictions whatsoever. You may copy it, give it away
or re-use it under the terms of the Project Gutenberg License
included with this ebook or online at www.gutenberg.org. If you
are not located in the United States, you will have to check the
laws of the country where you are located before using this
eBook.
Language: French
Mademoiselle
de Bressier
PAR
ALBERT DELPIT
DEUXIÈME ÉDITION
PARIS
PAUL OLLENDORFF, ÉDITEUR
1886
ebookbell.com