From J Wiki
Jump to navigation Jump to search
User Guide | Installation | Development | Categories | Git | Build Log

debug/lint - Static sentence checker and flow analyzer for J verbs

Browse history, source and examples using github.


Use lint in place of load to check your explicit definitions.

lint tries to find errors before a script is run. The idea is for 'lint' to replace 'load' during debugging. The errors it looks for are:

  • explicit definitions lacking trailing )
  • undefined names, including names not defined in all paths
  • verbs used with invalid valences
  • non-noun results at the end of condition blocks and verbs
  • syntax errors
  • sentences with no effect on execution (eg verb verb)

lint first loads the script, then extracts the explicit definitions and parses them one by one. Each definition is executed in the locale it is loaded into. Each line of the definition is executed in "safe mode" where verbs that have side effects, such as file operations, are not performed. Global variables are used by the execution, but all assignments are simulated without changing the global environment. The execution has access to any globals that are defined after the script is loaded (including definitions from other scripts)

If a verb uses global variables defined in another verb, the dependent verb should follow the defining verb in the script, and the NB.?lintsaveglobals directive should be used (see below). Any verb named 'create' or whose name ends with '_run' will automatically its globals made available to subsequent definition as if NB.?lintsaveglobals had been the last sentence of the verb.

Any changes to the locale must be made using the 'cocurrent' or 'coclass' verbs. The starting locale is 'base'.

Coding Tip: conditions that are meant always to test true should be left empty. This will produce better flow analysis. In other words, write

while. do. rather than while. 1 do.


elseif. do. rather than elseif. 1 do. in the last prong of a conditional

Lint Directives

Lint Directives are comments beginning with NB.?lint. These give additional control of the checking.

  • NB.?lintmsgoff suppresses display of messages starting with the next line
  • NB.?lintmsgon resumes display of messages starting with the next line
  • NB.?lintonly ... Executes ... (in safe mode) during checking. This is useful to establish a valid value for a name during checking, to avoid a syntax error.
  • NB.?lintsaveglobals Any global names that have been set by the current definition will be added to a list of such names that is passed in to later definitions. Use this when one verb is known to be executed before others, and creates globals that the later verbs depend on. Use in concert with NB.lintonly to solve other problems of initialization. Note that the definitions are the ones in effect when the directive is scanned.
  • NB.?lintloopbodyalways in the B block of for. or while., indicates that the loop body is always executed


usage: [msglevel] lint filenames...

y: The names of the scripts to be checked. For the nonce, only one script will be checked

result: Table of (line number);(error message) for each error. If there is no error, a congratulatory message is typed; if errors are found, a grid is launched to display the result if msglevel=0 (default), the error messages are emptied if a grid is displayed; if msglevel=1, the errors are always returned


Use JAL/Package Manager.

Load debug/lint addon with the following line:

   load '~addons/debug/lint/lint.ijs'

Example usage


Henry Rich

See Also