Why does +/@*: 1 2 3 give me 1 4 9 instead of 14?

You have

   +/ *: 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


Contributed by Please Identify

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.


Contributed by Your Name

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

   9!:49 (1)

or change the names to the new form by loading the script

   load '~system/extras/migrate/fixargs.ijs'

and then

  fixfile <'filename'  NB. e. g. <'c:\Jprogs\scriptname.ijs'

or

   fixpath 'pathname'  NB. e. g. 'c:\Jprogs'


Contributed by Your Name

Is there a BNF description of J?

No, nor can there be. BNFs describe context-free grammars, and J's grammar is not context free. A name's class (the type of that token) is determined at run time, and can change within a single executable statement. For example:

   x =. (x=.+/ . *)~ x =. i. 4 4

However, one can understand J's lexing and parsing without a BNF. The formal description of its lexing rules (rhematics/word formation) can be found in Part I of the Dictionary, and its parsing rules (syntax/grammar) in Part II § E.

An easier and more interactive introduction to J's grammar can be obtained from the trace script shipped with J. Simply load 'trace' and then trace 'J sentence' to see how the J sentence is parsed:

   load'trace'
   trace'(+/ % #) i. 5'
 --------------- 3 Adverb -----
 +
 /
 +/
 --------------- 5 Trident ----
 +/
 %
 #
 +/ % #
 --------------- 8 Paren ------
 (
 +/ % #
 )
 +/ % #
 --------------- 1 Monad ------
 i.
 5
 0 1 2 3 4
 --------------- 0 Monad ------
 +/ % #
 0 1 2 3 4
 2
 ==============================
2

Note that the trace facility only covers parsing, not lexing. For a clearer understanding of J's rhematics, one may study the definition of word formation (i.e. monad ;: in terms of dyad ;:).

   mjx=: ' ';(a.{~,65 97+/i.26);'0123456789_';'.';':';''''
   t=. 0 7 2$0 
   NB.        S    A    9    D    C    Q    X
   t=.t,_2]\ 0 0  2 1  3 1  1 1  1 1  4 1  1 1  NB. 0 space
   t=.t,_2]\ 0 3  2 2  3 2  1 0  1 0  4 2  1 2  NB. 1 other
   t=.t,_2]\ 0 3  2 0  2 0  1 0  1 0  4 2  1 2  NB. 2 alphanumeric
   t=.t,_2]\ 0 5  3 0  3 0  3 0  1 0  4 4  1 4  NB. 3 numeric
   t=.t,_2]\ 4 0  4 0  4 0  4 0  4 0  5 0  4 0  NB. 4 quote
   t=.t,_2]\ 0 3  2 2  3 2  1 2  1 2  4 0  1 2  NB. 5 even quotes
   sjx=: t
   
   f=: (0;sjx;<mjx)&;:
   f y=: '(2*a) %~ (-b) (+,-) %: (*:b)-4*a*c'
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+--+-+--+-+-+-+-+-+-+-+-+
|(|2|*|a|)|%|~|(|-|b|)|(|+|,|-|)|%:|(|*:|b|)|-|4|*|a|*|c|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+--+-+--+-+-+-+-+-+-+-+-+
   (f -: ;:) y
1
   (f -: ;:) '1 2 3 +/ . * 4 5 6'
1
   (f -: ;:) 'gm=: */ %:~ #'
1

If you're unfamiliar with finite state machines in J (i.e. dyad ;:) the Lab "Sequential Machines" provides brief introduction.

See Also
  • chat/2007-November/000678 J syntax easy to parse? I don't think so


  • Contributed by Your Name

    Why do/don't these match?

    Often it seems impossible to match items that seem identical. At other times we are surprised that "different" items do match. Some examples follow.

    Case sensitive

       'a' -: 'A'  NB. No surprise here
    0

    Rank

       1 ; ,1   NB. these look equal, but ...
    +-+-+
    |1|1|
    +-+-+
       1 -:  ,1 NB. a scalar vs a vector
    0
    
       1 2 3 ;  ,:1 2 3   NB. these look equal, too
    +-----+-----+
    |1 2 3|1 2 3|
    +-----+-----+
       1 2 3 -:  ,:1 2 3  NB. a vector vs an array
    0

    Type

       1 ; '1'   NB. these look equal
    +-+-+
    |1|1|
    +-+-+
       1 -: '1' NB. numeric vs literal
    0

    Unicode

       '∇' -: '▽'  NB. 16b2207 vs 16b25bd
    0

    Floating point tolerance

       1 = 1+1e_14
    1
       1 = 1+1e_10
    0

    Contributed by BrianSchott

    Why doesn't A * B matrix 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.

    The length error above is caused because, in J, for A * B to work, the frame of one must be a prefix of the frame of another, see dictb. In particular, if A and B are both matrices, then * is applied cell by cell and the shapes must match.

    J does have 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



    Contributed by RichardHill

    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

    Explanation

    +/'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.


    Contributed by Your Name

    Why +/ *: a works, but when I say foo =: +/ *:, foo a doesn't work?

    You have

       +/ *: 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

    What happened?

    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 $ y=x+2 $ into $ 3y $ you have to write $ 3(x+2) $ rather than $ 3x+2 $ .

    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.

    See Also


    Contributed by Your Name

    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.

    See Also


    Contributed by Your Name

    Why does ''trace'' produce an error?

    I got the following error. Can someone please elucidate?

       load 'trace'
       trace 'sp1 10'
    --------------- 0 Monad ------
    sp1
    10
    value error: sp1
    |   t_z=.    (sp1)(10)

    Trace currently does not support names which are unqualified by locale.

    Ideally, trace should determine the locale of the caller and use that. Or, since that may not be possible, it should assume the locale 'base' and use that. However, since it currently does not do so, you need to either not use names, or qualifiy them properly.

    These should work:

      sp1 =: (#~ 2 = #@q:) @ }. @ i.
      trace '(#~ 2 = #@q:) @ }. @ i. 10'
      trace 'sp1_base_ 10'

    Finally, note that trace just shows the stages of parsing. It does not show you how derived verbs work. For that, you need to perform experiments with related verbs. For example:

      (#~ 2 = #@q:) @ }. @ i. 10
    4 6 9
      (;~ 2 = #@q:) @ }. @ i. 10
    +-----------------+-----------------+
    |0 0 0 1 0 1 0 0 1|1 2 3 4 5 6 7 8 9|
    +-----------------+-----------------+
      (;~ #@q:) @ }. @ i. 10
    +-----------------+-----------------+
    |0 1 1 2 1 2 1 3 2|1 2 3 4 5 6 7 8 9|
    +-----------------+-----------------+

    Contributed by @BrianSchott@ from a post by RaulMiller

    Guides/Language FAQ (last edited 2008-12-08 10:45:40 by )