- Why does +/@*: 1 2 3 give me 1 4 9 instead of 14?
- Why does +/ % # 1 2 3 give me 0.333333 instead of the mean, 2?
- +/ *: a works, but when I say foo =: +/ *:, foo a doesn't work
- 1 2 3 makes a list of numbers, why doesn't a b c do that when they are all numeric?
- Is there a BNF specification for J?
- Why doesn't A * B multiply the two matrices A and B?
- How do I get the row sum of a table?
- Why do I get spelling errors when I write x. and y.?
Why does +/@*: 1 2 3 give me 1 4 9 instead of 14?
+/ *: 1 2 3 14
and the Dictionary says that
u@v y is u v y
so how come
+/@*: 1 2 3 1 4 9
The problem is the rank of the verb. u@v creates a verb whose rank is the rank of v. This verb is equivalent to u v y but it is applied to each cell of y independently. The rank of +/@*: is the same as the rank of *:, i. e. 0; so +/ *: y happens for each scalar in y independently, rather than summing across the scalars.
The solution is to make sure the combined verb has infinite rank, so it will be applied to the entire y operand. The preferred way to do that is by using @: rather than @ as in
+/@:*: 1 2 3 14
Why does +/ % # 1 2 3 give me 0.333333 instead of the mean, 2?
You want +/ % # to be treated as a "fork", a 3-element sequence of verbs (called a train of verbs). Often that train is defined and named as follows.
mean =: +/ % # mean 1 2 3 2
To be recognized as a fork, the train of verbs must be isolated from surrounding elements in a way that the J sentence parser recognizes. Parentheses around the fork or other verb train is another way to isolate the train, as shown next.
(+/ % #) 1 2 3 2
See also the next question.
+/ *: a works, but when I say foo =: +/ *:, foo a doesn't work
+/ *: 1 2 3 14
but when you make a verb to do the operation, you get
foo =: +/ *: foo 1 2 3 2 5 10 3 6 11 4 7 12
The complete story is a bit intricate, but you can get along quite well to begin with by imagining that the name of a verb is replaced by its value enclosed in parentheses. This is similar to mathematics, where if you want to substitute into you have to write rather than .
So, when you used your foo, it was as if you had written (+/ *) 1 2 3 which would give you:
(+/ *:) 1 2 3 2 5 10 3 6 11 4 7 12
We needn't concern ourselves with what (+/ *:) does (it's called a hook); all we need to know now is that it's not the same as +/ *: without the parentheses.
Correct ways to write foo are:
foo =: 3 : '+/ *: y' foo =: 13 : '+/ *: y' foo =: verb : '+/ *: y' foo =: +/@:*: foo =: [: +/ *:
It should be noted that the notion that a verb is replaced by its parenthesized value is fundamentally incorrect. That is just a way of thinking about the execution of a sentence that gets the correct result in normal cases. The actual processing is different, as described in the references.
1 2 3 makes a list of numbers, why doesn't a b c do that when they are all numeric?
J beginners, learning that 1 2 3 is a 3-element vector of numbers, often reach the erroneous conclusion that space is a concatenation operator in J, and that two nouns appearing side-by-side are concatenated. They are then surprised by
1 2 3 NB. create a list 1 2 3 a =: 1 b =: 2 c =: 3 a b c NB. Why doesn't this create the same list? |syntax error | a b c
Space is not a concatenation operator. , (comma) is the concatenation verb. Lists of consecutive numbers are a special case. They are recognized during the initial analysis of a sentence, before execution begins. a b c can't be recognized at that point, because the values of a, b, and c may change during execution of the sentence.
Is there a BNF specification for J?
There is not one and cannot be one, for J's grammar is not context-free. A name's class (the type of that token) is determined at run time, and can change its class within a single executable statement. For example:
x =. (x=.+/ . *)~ x =. i. 4 4
Why doesn't A * B multiply the two matrices A and B?
The problem is:
]A =: 2 3 $ 4 3 8 6 5 3 4 3 8 6 5 3 ]B =: 3 2 $ 5 4 9 6 4 2 5 4 9 6 4 2 A * B |length error | A *B }
A J array is not the same thing as a matrix in mathematics. A mathematical matrix is a two-dimensional array that follows the rules of scalar multiplication and matrix multiplication and addition. A J array can have any number of dimensions, and is not restricted to matrix operations.
In J, any verb can be applied to arrays, and the verb operates on cells of the array according to the rank of the verb. The key concept is the rank of verbs, which is discussed in the references.
J does have a few verbs that perform matrix operations: +/ . * for matrix multiply, %. for matrix inverse/matrix divide, -/ . * for determinant, and 128!:0 and 128!:1 for special matrix operations. To find the matrix product of A and B, use
A +/ . * B 79 50 87 60
How do I get the row sum of a table?
]t=:?.4 5$10 6 5 9 2 4 9 0 7 0 4 6 8 3 8 1 2 8 0 0 2 +/t NB. this is column sum 23 21 19 10 11
How do I get the row sum of a table?
Use Rank adverb
+/"1 t 26 20 26 12 +/ rows t 26 20 26 12 +/ items t 26 20 26 12
+/'s verb rank is _, which means + is inserted in between items (the highest rank cells). You need a verb with rank 1, which means + is inserted between atoms for each line.
Why do I get spelling errors when I write x. and y.?
Starting with J6.01, the period is removed from the argument names, so write x and y instead of x. and y. .
If you have code that uses the old names, you can either tell the interpreter to accept the old names by executing
or change the names to the new form by loading the script
fixfile <'filename' NB. e. g. <'c:\Jprogs\scriptname.ijs'
fixpath 'pathname' NB. e. g. 'c:\Jprogs'