Vocabulary/Dissect
Display And Probe A J Sentence Graphically
Wouldn't it be great if you could actually see how a sentence executes? Instead of staring at something like
z =. 100 200 300 +/ z + i. 3 3 609 612 615
you would see a picture, like the one at the right. And you could probe around and actually see which numbers are added to which.
You could even look inside complex verbs, so that instead of
[ z =. 3 9 6 */ 1 5 9 2 3 15 27 6 9 45 81 18 6 30 54 12 [ a =. 6 5 3 6 5 3 a ([ + (+/ % #)@]) z NB. Add a to average of z |length error | a ([+(+/%#)@])z
which leaves you scratching your head trying to see what part of the verb failed, you would get a picture of execution like the one at the left. You can see just what went wrong - you tried to add a list of length 3 to a list of length 4, which is an agreement error.
Dissect
The tool that gives you this and more is Dissect. It's a J Addon, so you first need to download it with Package Manager, and make sure you are running J602 or J803+. Load Dissect into your J session with
require 'debug/dissect'
and you can start dissection, with sentences like
dissect '+/ z + i. 3 3' [ z =. 100 200 300 NB. the first picture above dissect 'a ([ + (+/ % #)@]) z' [ a =. 6 5 3 [ z =. 3 9 6 */ 1 5 9 2 NB. the second
Normally you will use your IDE to launch Dissect using function keys.
Dissect has access to all names, even private ones, defined in the context in which it is invoked. So, if you turn on debugging, you can use Dissect to debug sentences running in an explicit definition.
Learning Dissect
Labs
Dissect includes two labs to help you get started. Download the labs using Package Manager.
Tooltips, Status Line, and Help
You can get immediate help about any block in the display by hovering over it. The Preferences menu controls the verbosity of the tooltips.
The status line, which is to the right of the navigation buttons, gives you a continuous one-line description of the block under the cursor.
If you want to read more, look in the Help tab of the menu.
Help From NuVoc (J8 only)
Function key F1 brings up the page you are now reading; shift+F1 brings up the opening page of NuVoc.
Clicking on a primitive verb in the rank stack will bring up the NuVoc page for it.
The Display
Dissect brings up a window giving the exploded view of your sentence.
Display Options
Dissect lets you decide how much detail you want to see about your sentence. Experts usually run with minimal detail, hovering over areas when they need more information. Novices often find the extra information helps them get oriented in the sentence they are dissecting. The main display options are illustrated here; other are described below.
The same sentence displayed with different detail levels
The Sentence
At the top of the display is the sentence being dissected. As you click around the display, Dissect will highlight the portion of the sentence corresponding to your clicks.
If you click in the sentence itself, the block describing the entity you clicked on will be brought to the center of the display. (not yet implemented)
Linking the Sentence to the Main Display
- Moving the cursor over a block causes the words of the sentence that created the block to be highlighted.
- Moving the cursor over a word of the sentence causes the block it creates to be highlighted, and also highlights all the words of the sentence whose results share that block.
- Clicking on a word in the sentence focuses the display on the result of that word.
An example of a display block whose result is shared by multiple words is
+/@:*: 1 2 3 NB. Add the squares of the atoms of y
The final result is the result of +/, but it is also the result of +/@:*:. If you move the cursor over / or @:, both will be highlighted.
Words that do not have any display block are grayed out in the sentence. A word that is executed under control of a modifier may have no display block until the modifier is expanded. In the example above, + has no display until / is expanded.
Nouns and Verbs
Each noun and verb result is displayed in a box. The flow of processing generally goes from top to bottom, with lines connecting outputs to inputs, and with the final result at the bottom. The parts of the display are described in the picture at right.
A noun has a display giving its name (if it was a named noun), its shape, and its value.
A verb has, in addition, a rank stack, a line for the shape of the result, and an optional selection line. The shape of the result is split into frame and result-cell shape sections.
Rank Stack
The rank stack shows the name of the verb, the rank of the cells it operated on, and also any modifiers that are consolidated with the display of the verb. In the example, the verb i. is a simple monad with rank 1. +"1"2 is a verb and two modifiers, all consolidated into a single rank stack. Each line of the rank stack thus represents a composite verb. In the example, the verbs are +"1"2, +"1, and +. The effective rank of each verb is shown. The background color of the rank indicates the selection level at which a single result-cell of the verb is selected, and matches the color of that portion of the frame corresponding to the frame of the verb.
Active and Inactive Rank
The rank shown in the rank stack is the effective rank: the rank that is actually used in the execution of the verb. If the rank of the verb is greater than or equal to the rank of the argument, the verb is applied to the entire argument and the effective rank is the rank of the argument. The rank of the verb is said to be inactive.
On the other hand, if the rank of the verb is less than the rank of the argument, the argument will be broken into cells. In this case the rank of the verb is said to be active and it is displayed in large bold italics to indicate its activity.
Indeterminate Rank
If a verb has multiple input cells, and a single one has not been selected, the effective rank of the verb is not known and will be shown as empty. An exception is made for the form u"n, where the rank of u does not depend on the selection.
Shape and Selection Lines
The shape line gives the shape of the result, divided into sections indicating where the shape comes from.
Shape Line: frame and shape
The frame of the verb result is color-coded to show how the parts of the frame correspond to the rank stack. The shape of a result cell is shown in white-on-purple following the frame. Taken together, the frame and the result-cell shape give the shape of the result.
Shape Line: Framing Fill
Each section of the shape except the first may reflect framing fill, if the result-cells did not all have the same shape. When framing fill has been added to a result, two shapes are shown, as in the example below:
- first comes the shape that was produced by the execution of the verb
- next, in parentheses, is the shape of the result after framing fill was added.
Until you select a result-cell, these values will be the same. If you select an individual result-cell, the selected shape will be smaller than the filled shape if the selected result required fill.
To find the rank of the result, concatenate the frame/shapes of each color, choosing the parenthesized filled value if it is given.
Selection Line
The selection line, which is the line below the shape line, gives the index list of your selection, if you have made any.
Entering Boxed Structures
The modifiers &.>, L:, and S: indicate operations inside a boxed hierarchy. Selection of a result-cell for one of these modifiers may result is selecting and opening boxes of the hierarchy. In this case, a > character is used in the shape and selection to indicate opening the box that has been selected by the previous indexing.
Results Of Nouns And Verbs
The atoms of a noun are verb are displayed in a 2-dimensional array. The color of the background indicates selections, and in general a light checkerboarding is used to make it easy to distinguish atoms.
Leading 1s In The Shape
When a value has leading 1s in the shape, the value is displayed in bold italic to alert you to the fact.
Crosshatching
Crosshatching calls your attention to special locations:
- Framing fill - atoms added when cells are joined into a final result - are shown with single crosshatching. If you select a fill cell completely, you can use the background color to see at what level the cell was added. A simple example of fill is shown at right
- An error cell - the place where execution failed - is shown with double crosshatching.
- An unexecuted cell, which was not filled because of earlier error, is shown with reverse single crosshatching.
Large Values
To keep the display manageable Dissect puts a user-selectable limit on the size of a displayed value. If a value exceeds this size, scrollbars are added to allow access to any value.
If you right-click a value with scrollbars, Dissect will bring up a window devoted entirely to the display of that value. You may scroll around this window and make selections, consequences of which will be shown on the main view. If the window has already been created, clicking on the smaller value will simply raise the existing window.
Right-clicking the data in the expanded window will close it.
A result block can be individually sized by dragging the sizing handle at the lower-right corner of the displayed values.
Ranks > 2
All values are displayed in a 2-dimensional array, as a table of characters. An atom or list is expanded to a table in the obvious way.
A rank-3 value is displayed as a list of 2-cells; that is, each 2-cell is displayed as a table, and the tables are arranged in a horizontal row.
A rank-4 value is displayed as a table of 2-cells similarly.
A rank-5 value is displayed as a list of 4-cells, and so on.
The boundaries of the 2-, 4-, and higher-cells are indicated by blue lines whose thickness increases with the rank they delimit.
The Type of the Result
Literal results are indicated by a very light green shading of the text color, to jog your awareness when you are dealing with strings that contain numeric characters.
If you want to know the exact type of a value, hover over it and read the tooltip.
Putting Results On The Clipboard
A right-click in the shape line of a result will put that result onto the clipboard, in 5!:5 format that can be executed as a J sentence.
A right-click in the selection line of a result will put that selected cell (without fill) onto the clipboard.
Looking inside named verbs
If your sentence refers to named verbs, the display will show the results of executing the verbs. You can look inside the execution of the verb by selecting a single result-cell and then right-clicking on the name of the verb:
- the verb will be reexecuted on the arguments for that result-cell.
- if the verb is a tacit definition, that execution will be dissected in a new dissect window
- if the verb contains an explicit definition, the execution will run under the debugger. A stop will be set on every line of the definition, so you can step through its execution.
Modifiers and ][
Dissect uses graphical cues to show you what's going on in your sentence. The connective elements of J - all those techniques for specifying how verbs are connected - do not explicitly appear. Their effects show in the connections formed between verbs and nouns.
The components that disappear into the wiring are:
- connective modifiers: @ @: & &: &. &.: ~ (u :v)
- invisible modifiers: hooks and forks
- verbs for directing operands: ] and [
- assignments
Modifiers whose only function is to affect rank or level are subsumed into the rank stack of the verb they are attached to. These modifiers are:
- " L: S: &.> each
- x u/ y
- u^:n and u^:v when n or the result of v is not an atom
- dyadic m&v and u&n
The modifiers m} (both monad and dyad) are displayed like ordinary verbs, but their arguments are analyzed to give more specific error messages, and clicking on a part of the result highlights the relevant arguments.
Other modifiers are attached to their operands to produce a verb that is displayed like any other. A growing number of these modifiers are supported by code that will allow you to see the details of their operation by clicking on the result.
Selection and Highlighting
The basic rule is, if you want to get more information on a result, click on it. Clicking will perform selection. If you have already clicked on something, clicking again will give more detailed information.
A selection click selects a cell of a result. Selection is possible when a result contains more than one cell. If the cell you selected is a result cell of a chain of verbs, the selection will be transmitted to the other verbs in the chain, and cause them to display their contributing values. The selected portions of the verbs in the chain are displayed in identical colors.
If the rank stack for a verb contains more than one row, each row represents a potential selection. As you click on an atom, smaller and smaller cells will be selected until you have finally selected a single result cell.
In addition to transmitting the selection to contributing verbs, a selection will highlight that portion of a verb's argument that contributes to the cell's value, by drawing color-coded rectangles around the relevant parts.
Computational Elements and Expansion Nodes
Computational elements control computation by selecting partitions or subtrees of the operands, changing what verb is executed, specifying the number of times a verb is executed, or invoking a recursion. These elements are:
- u/ y
- m/ y as long as m is created by using ` (the Tie conjunction)
- u^:v
- u^:(v0`v1`v2) and u^:(v1`v2)
- u^:n as long as n is created by using ` (the Tie conjunction)
- Selective modifiers u\ u/. u\. u;.n
- Selective modifiers m\ m/. m\. m;.n as long as m is created by using ` (the Tie conjunction)
- m@.v
- $: (recursion)
- u ::v (execute v if u fails)
These expandable elements are indicated by a dashed box around the bottom verb in the rank stack. When you click on the result of one of an expandable elements, a new block (called an expansion block) is created, showing all the intermediate results of the element. You can then click on one of those results to inspect it or see where its operands came from. An example is shown at right.
Undisplayed Results
Selection is essential for analyzing the execution of verbs of the form u@v, u&v, and u&.v. For these forms, it makes no sense to ask "what is the result of v?", because v is executed on each argument cell of the combined verb, and the results of those executions may have different shapes and even different types, so that they could not be considered part of a single result.
Verbs such as the v in the cases listed above are displayed with no result until a result cell has been selected. At that time, the result-cell of v that contributes to the next verb in line will be revealed.
Experiment to see how undisplayed results can come to life. Good examples are:
dissect 'i.@> 2;1 3;3 1' dissect '#@> ;: ''there is a tide''' dissect '#@:> ;: ''there is a tide'''
Finding Errors
Dissect is on your side when your sentence has an error. It will automatically zero in on the error by selecting the failing cell for every verb in the failure path, so that the initial display will be pointing right to the error.
The offending verb will have a big error indicator showing where the problem is. In the picture on the left you can see that the error occurred when you tried to execute i. on the value 0.5.
Special Errors
Dissect provides more detail about errors in some cases:
Dissect Error J session reports as Meaning agreement length error Dyad operands do not agree (one frame is not a prefix of the other). The entire failing verb will be lumped together in this display. The reason for this special treatment is that agreement error can be detected on execution of hooks and forks, and these have no display to associate the error with. framing domain error The results of a verb cannot be assembled into a single noun because they have dissimilar types. invalid verb domain error The execution of a modifier produces an invalid verb, such as +@2 . invalid v value domain error or index error In u@.v, the result of v is invalid as an index into the gerund u . non-atomic v domain error In u@.v, the result of v is not an atom. incompatible selectors domain error In x m} y, the selectors in m select regions of y that have different shapes. selection too long length error In x u;.3 y, x specifies more axes than y has. selector invalid index error In x m} y, a complementary selector is not a single atomic box. selector rank rank error In x { y or x m} y, the selectors (>x or >m) have rank > 1. selector level domain error In x { y or x m} y, a selector has boxing level higher than 3. selector too long length error In x { y or x m} y, a selector specifies more axes than y has. xm agreement domain error In x m} y, $x must be a suffix of $m{y no neutral domain error In u/ y, where y is empty, u must be a verb known to the interpreter for which it can create a neutral.
Arrow Keys
Once you have selected a cell, you may use the arrow keys to move the selection to adjacent cells.
Scrolling The Display
Dragging the display
To scroll the display within the window, click any empty point on the screen and drag it.
Highlighting a Wiring Network
Clicking-and-holding on a wire will highlight all the places that share the value on that wire.
Scrolling to a specific result
To see the result of a specific word in a sentence, click on that word in the sentence at the top of the dissect display. The result of the selected word will be centered on the focus point which is three-quarters of the way down the onscreen portion of the display.
Sizing the Display
The window is initially big enough to hold the entire dissected sentence (plus a margin for tooltips, depending on the verbosity level you have selected for tooltips). As you make selections, the window will automatically be enlarged as needed.
If you resize the window manually, automatic resizing will be suppressed. To restart automatic sizing, double-click any empty point on the screen.
Sizing individual blocks
Blocks that are big enough are supplied with a resizing handle, a small square at the lower-right corner of the data area. Click and drag the resizing handle to change the size of the data area. The screen with be redrawn when you release the mouse, possibly with the blocks laid out in a different pattern.
Double-clicking the resizing handle without moving it makes the block big enough to display the entire result (subject to dissect's internal maximum size, which is a fraction of the window-size). If the block has already been resized, double-clicking the resizing handle reverts the block to its original size.
Details
Determinate Nouns
Consider the lines
x =. 3 1 4;1 5 9 2 6 z =. ((+/ % #)&.> x) , < (i. 4) ; (i. 4 5)
This falls into two parts:
- Boilerplate: < (i. 4) ; (i. 4 5) doesn't change, and you probably don't need to see the details of how it is generated
- Kernel: ((+/ % #)&.> x) which is probably where the interest is.
A determinate noun is a noun whose value does not depend on any external value. The boilerplate above is an example. Initially the display of a determinate noun is omitted if its value is used only to calculate other determinate nouns. If you want to see the detail that went into calculating a determinate noun, click on its value.
Exception: if the entire sentence you are dissecting is determinate, you will automatically see all detail.
Niladic verbs and Constant verbs
The verbs _9: through 9: are syntactically verbs, but they ignore their arguments: they are niladic. Dissect does not display their inputs.
Any noun can be made into a constant verb by assigning a rank. If the assigned rank is infinite (e. g. 'abc'"_), dissect suppresses display of the inputs to the constant verb.
Options
Options can be engaged by making selections in the menu.
- Preferences
- Font Size
- Tooltip Font Size
- Display Precision - number of significant digits for floating-point results
- Show ][ - show display blocks for [ and ] rather than discarding them
- Show Full Compound Names - in the rank stack, show the full compounds instead of merely the modifier that created them
- Show @ @: - create rank-stack entries for @ @: & &: &. &.:
- Show u/ on 2 items - when the y in u/ y has only two items, replace the display of u/ with a display of dyad u. This simplifies the display in this common case.
- Show argument fill-cells - insert a * character into the shape line when a frame contains 0, which means that the verb was executed on a cell of fills. The rank stack will also have * following the rank at the place where the fill-cell was inserted. If execution on the fill-cell resulted in error, that fact will be noted.
- Sizes
- Tooltips (control font size and level of chatter)
- Config (save the current options setting, or revert to saved settings)
Errors Before Dissect Runs
Errors During Parsing
Dissect requires that the sentence produce a noun result. If the sentence produces any other part of speech, you must modify your sentence.
If your sentence fails with a syntax error, dissect might still help you. In some common parsing errors, it can narrow down the error.
({.~' 'i:~)each "1> < ;._2 each ,&',' each LF cut 'abcdefgh' |domain error | ( {.~' 'i:~)each"1><;._2 each,&','each LF cut'abcdefgh' dissect '({.~'' ''i:~)each "1> < ;._2 each ,&'','' each LF cut ''abcdefgh''' Syntax error: execution of monad not at the end Error snippet: {. ~ ' ' i: ~
The error was a misplaced noun, which dissect localized.
In some other errors detected during parsing, dissect is more informative:
(16&^ ; 3@+ , 4&-) 6 |domain error | (16&^; 3@+,4&-)6 dissect '(16&^ ; 3@+ , 4&-) 6' domain error: operands to @ must be verbs
+`-;.3 i. 4 5 |nonce error | +`-;.3 i.4 5 dissect '+`-;.3 i. 4 5' domain error: gerund u not supported for u;.3 and u;._3
Incorrect Execution
Dissect runs your sentence twice, with instrumentation and without. If the results of the two executions are different, dissect reports that fact and prompts you to see whether you want to continue.
There are three main reasons for a sentence to mismatch:
- a dissect bug, which you should report
- an irreproducibility in your sentence causing it to give different results on successive executions
- a bug in special code in the J interpreter.
If your verb is irreproducible, you might consider turning off result checking.
Bugs in interpreter code show up because the heavily-instrumented version of the sentence that dissect uses to collect data is not eligible for any special code tricks. If the special tricks fail, so will dissect.
1 2 3 ["0 i. 3 4 1 2 3 dissect '1 2 3 ["0 i. 3 4' dissect error: dissected sentence has incorrect result
The way to check for an error in special code is to modify the form slightly and see if the result changes. The safest modification is to replace a verb u with (u"u)
1 2 3 (["[)"0 i. 3 4 1 1 1 1 2 2 2 2 3 3 3 3
This is the correct result.
Implementation Status
With the exceptions noted below, Dissect will display any J sentence that produces a noun result.
Some language features are recognized but not understood by dissect and are displayed as generic entities. They are listed here in the planned order of future support:
- u@.n (atomic n only)
Some language features cannot be supported fully:
- Inverses cannot be dissected. They are displayed as monolithic verbs. Adding the instrumentation necessary to dissect an inverse sometimes makes a verb that J cannot invert; in other cases asking J to find an inverse causes it to hang.
Some language features are not supported properly:
- Explicit modifiers (produced by m : n) must produce a verb result, and m must be a single number or name
- AR assignments and assignment to non-nouns are not allowed
- Recursion that has valence different from the valence of the original verb is not allowed
How To Save Typing
Often-dissected Lines
Three important special arguments:
dissect 0 NB. to dissect the line under the cursor (in J8) dissect 1 NB. to dissect the last line that failed dissect 2 NB. to dissect the line on the clipboard
Mapping Dissect to PF Keys
Add the following code to your startup script to use Dissect from a function key. You will have two control keys, one to dissect the line under the cursor, the other to dissect the last failing line.
J6.02
This uses PF4 to dissect the line under the cursor, and PF5 to dissect the last error.
cocurrent 'jijs' NB. y is 0 to dissect last error, '' to dissect selection rundissectline =: 3 : 0 if. -. (<'dissect') e. 18!:1 (0) do. return. end. save 1 if. 0-:y do. runimmx1 'dissect 0' else. runimmx1@('dissect '&,)@quote^:(*@#) getline'' end. ) jijs_f4_fkey =: rundissectline jijs_f5_fkey =: rundissectline bind 0
Change the f4 and f5 in the last two lines to use different keys.
J8.03 and later
Put lines such as the following into the Edit>Configure>User Keys window:
F2;0;Dissect Line;dissect&.finddissectline_dissect_ 0 F3;0;Dissect Last Error;dissect&.finddissectline_dissect_ 1 F4;0;Dissect Clipboard;dissect&.finddissectline_dissect_ 2
Here F2, F3, and F4 are the keys selected for Dissect:
- F2 runs dissect on the selected line
- F3 runs dissect on the last line that produced an error
- F4 runs dissect on the text that is on the clipboard
In The Debugger (JQt only)
Two buttons invoke Dissect:
- The Dissect current/cursor line button will run dissect: on the selected line if there is one, otherwise on the current line (that is, the line about to be executed if you single-step).
- The Autodissect on stop button toggles autodissect mode, under which dissect is automatically executed on the current line whenever execution stops. In autodissect mode, as you single-step through your program you see every line dissected as you go.
When Dissect is called from the debugger, it does not execute assignments, so as not to interfere with normal program operation.
Advanced Features
Giving a left argument to Dissect allows you to engage options.
x contains boxed name;value pairs, either as a list or as a table with one pair per row. The allowable names and the corresponding values are as follows:
Name Value meaning title fontsizeTABtext text will be displayed as a title. The font will be adjusted by the amount fontsize. link fontsizeTABtextTABurl text will be displayed a box of links at the top-left of the screen. The font will be adjusted by the amount fontsize. If the user clicks on the link, the browser will display the page url. datasize vpct hpct The second column holds a string which will be converted to numeric. The number are percentages, which must be in the range 10-90, indicating the maximum amount of the screen-size to allow for the display of a single value. Vertical and horizontal can be controlled separately. check all, shape, error, or no Level of checking. all=full checking, shape=check shapes and type, ignore values, error=check only for error, no=no checking, run sentence only once sandbox 0 or 1 (default |0) When 1, dissect runs the sentence in a sandbox, a special explicit definition that reproduces the sentence's original environment. By default, the sentence is forwarded back to the context in which dissect was called. The sandbox can only be used when the y argument to dissect is a boxed table containing all the names to be defined. returnobject 0 or 1 (default |0) Return the locale that was created. By default, dissect always returns a byte list: normally empty, but nonempty if there is an error. With this option is set, dissect will return the locale of the instance for the form that was created, as an atomic box. If there is an error, there will be no form and the error message will be returned as a byte list. destroy__returnedvalue '' will remove the dissect form. noassignment 0 or 1 (default |0) Suppress assignments. When this option is set, assignments are deleted from the sentence that is executed. It is then an error to perform an assignment to a name that is used later on in the sentence. fromdebugger 0 or 1 (default |0) Debugger active. Set when dissect is called from the debugger, used to change certain error messages.
Turning Off Checking
By default Dissect runs your sentence both as is in the J session, and in the instrumented form used to trace execution. This will necessarily fail when the sentence is unreproducible, for example if it uses random numbers. The flag settings to turn off checking are ('check';'no'):
dissect '10 ? 10'
will give a dialog box because of the mismatched results.
('check';'no') dissect '10 ? 10' NB. dissects properly
Compatibility With Earlier Releases
A different format for the options, used in early releases of Dissect, is still supported for compatibility.
In this format, the first atom of x, which may be boxed, is an integer whose low 4 bits are interpreted as specifying the values for the options fromdebugger (bit 3), noassignment (bit 2), returnobject (bit 1), and sandbox (bit 0). The second atom, if present, is a box containing a table of (name;value) options as described above.
Requests and Bug Reports
Add em here.