Deciphering J expressions, using aids from aatrace.ijs
Even after several years of acquaintance with J, I am often puzzled by the results claimed for a published computational expression, or surprised by the result--or non-result--from one of my own. Some of these puzzles have been resolved by brief study of relevant Vocabulary definitions and examples. Some have needed a bit of experimentation with various argument values, sizes, and shapes. A great many have required detailed analysis of symbol categories and revision of parenthesization and/or order.
After a first round of pondering and experimentation, I have often resorted to automated analyses of parenthesization, syntactic structure, and value production found in the publicly distributed script trace.ijs and the Foreign conjunction 5!:4 . These tools have often helped to locate the causes of my difficulties, but not always as easily or as fully as I would have liked. I have now added some additional versions of those capabilities in a script, aatrace.ijs, linked via http://www.jsoftware.com/jwiki/ArtAnger . They are briefly summarized below.
I think that newcomers to J should be encouraged very early to use such tools, which supply multiple avenues to understanding concrete examples. Some of my recent puzzlements might not have occurred if I had had a better grounding in the precise nature of the syntactic features of J. Admittedly, use of additional non-ASCII symbols, color, pixel graphics, slide-show sequences, motion, sound, and/or interactive query of values at each point may be able to convey these ideas more fully or more memorably, but text-based tools may still offer the most generally usable format with the fewest obstacles in equipment, software, setup, or training.
The public verb paren inserts parentheses around every sub-expression which gets evaluated as such during interpretation. This shows whether each token (symbol for an operation or value) is used first with a token on its right or on its left, and may help to resolve an issue based on that type of misunderstanding. In a long expression, it is usually difficult to identify visually the precise extent of each parenthesized group, and thus to understand important details of how they are to be evaluated. aatrace offers two additional tools.
The pyr verb redisplays a quoted expression with each parenthetical subgroup raised one line above its context, forming one or more pyramids of various heights, determined by the degree (depth) of nesting at each position.
pyr '-(b+ _1 1* ((b^ 2)- 4* a* c)^ 0.5)% 2* a' (b^ 2) ( ____ - 4* a* c) (b+ _1 1* _______________ ^ 0.5) - _______________________________ % 2* a
The parenpyr verb applies paren to delineate all the syntactic groupings, and pyr to improve their visual recognition.
parenpyr '-(b+ _1 1* ((b^ 2)- 4* a* c)^ 0.5)% 2* a' 8 (^ 2) (a * c) 7 (b ___ ) (4 * _____ ) 6 ( _______ - ___________ ) 5 ( _________________________ ^ 0.5) 4 (_1 1 * _________________________________ ) 3 (+ __________________________________________ ) 2 (b ______________________________________________ ) (2 * a) 1 ( __________________________________________________ % _____ ) 0 (- ______________________________________________________________ )
The predefined conjunction 5!:4 produces a tree diagram which may help to show the relationships among the components of a named compound verb. It accepts the boxed, quoted name, not a quoted expression. If any arguments are supplied when assigning the name, some evaluations may occur at that moment, and only those results will appear at those places in the output tree.
This tree representation shows clearly that the result from each subtree contributes to some operation to its left, or is the sole final output. Each subtree has two or three visually equivalent right branches, for the left argument (if present), verb (or adverb or conjunction), and right argument. When the argument(s) and operation are all represented by assigned names or further subtrees, it takes an extra level of mental analysis to recognize which does what. aatrace offers an alternative.
The flowtree verb produces a "tree" with different orientation and operation placement. It does not require assigning the expression and boxing that name, so it can show all the steps of an evaluation even when operands are provided. While an arithmetic formula may be read mainly from left to right, and interpreted by J mainly from right to left, in this tree form the subgroupings are connected downward from innermost to outermost. Where sub-expressions evaluate independently, they appear in their original relative left-right relationship, but perhaps at different levels. The "tree" depicts a generally downward flow of information (data). The flows of left and right operands to a simple verb meet above the verb's name and a single connector (or pipeline) to it.
(These diagrams should be displayed in a fixed font; Courier New works well.)
'a_jtrace_ b_jtrace_ c_jtrace_'=: 1 _3 2 flowtree '(b+ _1 1* ((b^ 2)- 4* a* c)^ 0.5)% _2* a' a c └┬┘ b 2 4 * └┬┘ └┬─┘ ^ * └─┬─┘ - 0.5 └───┬───┘ _1 1 ^ └────┬────┘ b * _2 a └───┬────┘ └┬┘ + * └────────┬─────────┘ % │ ((b + (_1 1 * (((b ^ 2) - (4 * (a * c))) ^ 0.5))) % (_2 * a)) 2 1
These diagrams deviate, however, from simple tree structure when displaying hooks, forks, ties, adverbs, and most conjunctions, to try to clarify the more complex processing paths which they represent. When an adverb, rank specifier, or other conjunction controls a verb's input and output, that modifier is enclosed and attached by an upper input bus to, and a lower output bus from, the verb to suggest the modified data flow.
flowtree '5 7 +"1 i. 3 2' 3 2 │ 5 7 i. └┐ ┌┘ ┌┴─┴┐ ┌─┌─┤ 1│ + ┌┤ "┘│ └─┘└─┬─┘ │
A Hook, Fork, or Tie train is capped with a common bus for distributing its external arguments to its internal verbs, and marked with an F, H, or T to highlight these deviations from normal syntax.
flowtree '7(* + -) 3' 7 3 └┬F┬┘ * - └┬┘ + │ flowtree '7(* * + -) 3' 7 3 └┐H ┌┘ │ └┬F┬┘ │ * - │ └┬┘ │ + └─┬─┘ * │
Left-input to a verb formed with Bond (&, or &:) is marked with an R as a reminder that a "third argument" is possible, serving as a Repetition factor (or "power"), able to cause mysterious errors.
flowtree '3(* 2&+ -) 7' 3 7 └┬F┬┘ * - ┌┴R┴┐ ┌─┌─┤2 │ + ┌┤└& │ └─┘└─┬─┘ │ 3 (* (2 & +) -) 7 38
A verb formed with Compose (again, &) or Appose (&:) is so marked, and shows a doubled connector, to call attention to the second-argument juggling which can happen there. A verb formed with Atop (@) or At(@:) attaches those markers to the usual sequence connectors as a visual aid in relating to the linear expression (and perhaps denoting infinte-rank application).
flowtree '[ + i.&$@]' │ │ └┬F──┬┘ │ ] │ @│ │ $ │ &┌┴┐ │ └┬┘ [ i. └─┬─┘ + │
The public verb trace lists the arguments and result of each sub-phrase as it is performed, to x (or _) levels of function calls, showing rank, shape, type, and value. Each action type is labeled according to the parse table in Section II.E of the J dictionary. The result of a sub-phrase may be a verb, so the trace reports the combined verb, and later reports only the final result of applying that combination to its operands.
A flowtree analysis stores, in addition to returning a diagram, two versions of the input expression. ParExpr is a fully parenthesized version; TrExpr is the same expression expanded by insertion of calls to a tracing adverb at each point where a verb or verb phrase is performed. A report of arguments supplied and results produced by each performance at each of those labeled points can be produced by executing that phrase. (It may first be edited to supply or alter values, or to remove tracing from the better understood actions.) A summary is stored in TR; the full values recorded for a point labeled n are stored in TRn (TR3, TR_2, etc.). These analyses can show very clearly how Insert applies a verb successively within a list, and how data are passed through the verb phrases in a Fork train.
(b (+ Ar 2) (_1 1 (* Ar 4) (((b (^ Ar 8) 2) (- Ar 11) (4 (* Ar 13) (a (* Ar 15) c))) (^ Ar 18) 0.5))) (% Ar 21) (_2 (* Ar 23) a) ('Label'; 'Left;Right;Result'), }:"1 colboxm TR ┌─────┬─────────────────┐ │Label│Left;Right;Result│ ├─────┼─────────────────┤ │21 │_4 _2;_2;2 1 │ │2 │_3;_1 1;_4 _2 │ │4 │_1 1;1;_1 1 │ │18 │1;0.5;1 │ │11 │9;8;1 │ │8 │_3;2;9 │ │13 │4;2;8 │ │15 │1;2;2 │ │23 │_2;1;_2 │ └─────┴─────────────────┘ TR2_jtrace_ ┌──┬────┬─────┐ │_3│_1 1│_4 _2│ ├──┼────┼─────┤ │b │+ │_1 1 │ └──┴────┴─────┘
The script is aatrace.ijs, downloadable via
After loading, help '' will show a summary of the main functions.
Art Anger - July 2012