Help / JforC / Declarations
>> << Pri JfC LJ Phr Dic Voc !: Rel NuVoc wd Help J for C Programmers
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 typechecking, making sure that objects pointed to are of the expected type. This is an example of making a virtue of necessity. Since J avoids pointer trouble much more directlyby not having pointers at allyou 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 userwritten 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 2dimensional arrays. Part of your verb definition will indicate that fact. If your verb is executed with an argument that is a 3dimensional array, J will automatically split the 3dimensional array into a sequence of 2dimensional arrays, call your verb for each one, and put the results 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 ndimensional array of rank ixjx...xk 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.
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 and can contain components of different types, 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.
An atom is a degenerate array, with no axes, but it follows the rules for arrays nonetheless.
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 rank3 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 4x5 array of elements, each with rank 1 and shape 6, or as a 4x5x6 array of rank0 atoms. These smaller arrays, which can be arrayed together to constitute the larger array, are called cells. As seen in the example above, the axes of a cell are a suffix of the axes of the entire array. A cell of rank k is called a kcell: a 0cell is an atom, a 1cell is an element of rank 1, a 2cell is an element of rank 2, and so on. You can view an array as an array of its cells, and in more than one way, depending on what cellsize you choose.
Each time you operate on an array, you decide the rank of the cells to be operated on. The rank of the cells is not a property of the array; rather, it indicates how you want to group the atoms of the array for a single operation. When you have decided to operate on cells of rank n, you can think of your noun as an array of ncells; the shape of that array of cells is called the frame of the noun relative to ncells. 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 6atom 1cells are arranged in a 4x5 array; this is the meaning of the frame of the 1cells. The four 5x6 2cells are arranged as a vector of 2cells; 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 5x6 array (i. e. a 2cell); q[1][0] is a 6element vector (i. e. a 1cell); q[2][0][3] is a scalar (0cell).
The noun q we have been using as an example can be thought of in any of the following 4 ways:

Frame 
Cells 

as an array of 
Length 
Value 
Rank 
Shape 
0cells 
3 
4 5 6 
0 
(empty) 
1cells 
2 
4 5 
1 
6 
2cells 
1 
4 
2 
5 6 
3cells 
0 
(empty) 
3 
4 5 6 

Choosing Axis Order
Because J verbs operate on cells of nouns, you should choose an order of axes that makes the cells meaningful for your application. Referring to the figure, we can see that the groups of items that fall into horizontal strips (1cells) or horizontal slabs (2cells) will be easy to operate on individually. Vertical strips or slabs will not correspond to cells and so will not be accessible individually; to work on them we may have to reorder the axes of the noun to make them correspond to cells. Such reordering of axes is easy in J but it can often be avoided by ordering the axes properly in the first place.
Negative CellRank; Items
In some cases, you may know the length of the frame and want to define the cells to have whatever rank is left over (for example, you may have a noun with one cell per employee, but you may not know the rank of the cells). We say that you are selecting the cells of the noun relative to the given frame. Negative cellranks indicate this. A _1cell has the shape corresponding to a frame of length 1 (5 6 in our example), a _2cell has the shape corresponding to a frame of length 2 (6 in our example), and so on. If the specified frame is longer than the rank of the noun, the entire shape of the noun is used for the frame (and the cells are 0cells, i. e. atoms). In our example, a _3cell, a _4cell, a _5cell, etc., all refer to atoms. As an important case of this, the _1cell of an atom is the atom itself.
_1cells are so important in J that they are given the name items. Our example has 4 items, each of shape 5 6 . An atom has one item, itself.
Remember: an atom has one item: itself.
The index of an item in an array is the sequence number of the item from the beginning of the array. The first item in an array has the index 0, just as in C.
Lists
When we choose to view a nonatomic <st2:Sn w:st="on">array</st2:Sn> (i. e. an array of rank 1 or higher) as a collection of its items, we say that the array is a list of its items. In our example above, the items of the 4x5x6 array are 5x6 arrays, and we say that the whole array is a list of 4 items each with shape 5 6 (equivalently, we say that it is a list of four 5x6 arrays). So many of J's primitives operate on items of their operands that we will find ourselves usually thinking of an array as a list of its items.
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 (onedimensional 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 rank1 arrays 'lists'. A list can also be called a vector.
Phrases To Memorize
A nonatomic 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 kcell.
The frame of a noun with respect to kcells is the shape of the noun, with the last k atoms of the shape removed.
The terminology of nouns is summarized in the following table.
Summary of Terminology for Nouns in J 


Atom 
NonAtomic Array 

Rank 
0 
1 
2 
higher n 
Name 
Atom 
List 
Table 
Rankn Array 
Shape (always a list) 
(empty list) 
1item list ,l 
2item list r,c for an rxc table with r rows and c columns 
nitem list 
Items 
The atom itself 
atoms 
lists (each with shape ,c) 
(n1)cells 
Name/Shape if 
impossible 
empty list 
empty table 
empty array 
,0 
0,c 
0,... 

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 singlecharacter 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.
Arraycreating 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 arraythere are no special 'declaration' verbsbut 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 .
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 1cell 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 rank2 array as a sequence of lines, one for each 1cell.
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 1item 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 1item list are identical. Does that mean that a scalar is the same thing as a 1item list? No. I mean no. NO! They are not (I say this with the 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 4item 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 0length list, as we have seen.
$ 1 $ 2 1
Remember, all sentences are executed righttoleft, so this is $ (1 $ 2), which gives the shape of the 1item 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 scalaran empty list.
$ 'a'
A single character is an atom, whose shape is the empty list.
$'abc' 3
A 3item 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 singleitem 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.
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 5item 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 1cells, 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 rank3 array. J displays the 2cells with a blank line in between. Similarly, a rank4 array is displayed as all the 3cells with 2 blank lines in between, and so on for higher ranks.
We have seen that the display of a zerolength list is a single blank line: proper, as there is one list, and it has no items. The display of a rank2 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)?
3 1 $ 2 5 $ 1 10 2 3 $ 2 5 $ 1 10 15
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 rank2 result.
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 rank3 result.
i. 0
A list of 0 items.
i. _5 4 3 2 1 0
When the argument is negative, the absolute value is used for the shape, but the items run in reverse order.
>> << Pri JfC LJ Phr Dic Voc !: Rel NuVoc wd Help J for C Programmers