Chapter 26: Script Files

A file containing text in the form of lines of J is called a script-file, or just a script. By convention a script has a filename terminating with .ijs . The process of executing the lines of J in a script-file is called "loading" a script.

We write our own scripts for our particular programming projects. In addition, the J system comes supplied with a library of predefined scripts of general utility.

We look first at built-in functions for loading scripts, and then at a few utilities.

26.1 Creating Scripts

Here is an example of a tiny script. It is supposed to show a number of definitions and then a computation. The lines of J look like this:

       plus =: +
       k    =: 2 plus 3
       k plus 1   

Scripts are usually created using a text editor, but here it is convenient to use J to create small examples of scripts as we need them. We can create this script with a filename of say example.ijs using the built-in verb 1!:2, like this:

   (0 : 0) (1!:2) < 'c:\example.ijs'
plus =: +
k    =: 2 plus 3
k plus 1   

26.2 Loading Scripts

There is a built-in verb 0!:1 to load a script. The argument is the file-name as a boxed string.

   0!:1 < 'c:\example.ijs'
      plus =: +
      k    =: 2 plus 3
      k plus 1

We see on the screen a transcript, or execution log, showing the lines of the script as they were executed, together with the result-values of any computations. The definitions of plus and k are now available:

plus k

Now we look at some variations on this basic theme.

26.3 With or Without a Transcript

To suppress the transcript we can load with 0!:0

   0!:0 <'c:\example.ijs'

We see nothing on the screen. The value computed in the script for k plus 1 is discarded. As well as 0!:0 and 0!:1 there are more variations of 0!:n - see the Dictionary.

26.4 Local Assignments in Scripts

Here is an example of a script.

   (0 : 0) (1!:2) < 'c:\exa.ijs'
w   =: 1 + 1
foo =: + & w  

Suppose that variable w has the sole purpose of helping to define verb foo and otherwise w is of no interest. It would be better to make w a local variable.

w can, in effect, be made local to the execution of the script on two conditions. The first is that we assign to w with =. in the same way that we assign to local variables in explicit functions. Our revised script becomes:

   (0 : 0) (1!:2) < 'c:\exb.ijs'
w   =. 1 + 1
foo =: + & w  

The second condition is that we load the script inside an explicit function, so there is something for w to be local to. (Outside any explicit definition that is, "at the top level", =. is the same as =:)

All that is needed is the merest wrapper of explicit definition around 0!:0 or 0!:1. A suitable "localizing loader" verb might be:

   LL =: 3 : '0!:0 y.'

If we now load this script

   LL < 'c:\exb.ijs'

and then look at the results:

foo w

we see that foo is as expected, but there is no value for w. Therefore w was local to the execution of the script, or strictly speaking, local to the execution of LL.

26.5 Local Verbs in Scripts

In the previous example, the local variable w was a noun. With a local verb, there is a problem. Here is an example of a script which tries to use a local verb (sum) to assist the definition of a global verb (mean).

   (0 : 0) (1!:2) < 'c:\exc.ijs'
sum  =. +/
mean =: sum % # 
   LL < 'c:\exc.ijs'

We see that this will not work, because mean needs sum and sum, being local, is no longer available.

sum % #

The remedy is to "fix" the definition of mean, with the adverb f. (as we did in Chapter 12). Our revised script becomes

   (0 : 0) (1!:2) < 'c:\exd.ijs'
sum =. +/
mean =: (sum % #)  f.

Now mean is independent of sum

   LL < 'c:\exd.ijs'
+/ % #

26.6 Loading Into Locales

We looked at locales in Chapter 24. When we load a script with 0!:0 or LL the locale that becomes populated with definitions from the script is the current locale.

By default, the current locale is base. In general, we may wish to load a script into a specified locale, say locale foo. Evidently we can do this by switching to locale foo loading and switching back to the base locale.

    18!:4 'foo'
    0!:0  <'c:\example.ijs' 
    18!:4 'base'

A neater way is as follows. We define a loading verb, LLL say, which is just like LL above but this time we install it in locale z.

   LLL_z_ =: 3 : '0!:0 y.'

Now we can load a script into a specified locale, foo say, with:

   LLL_foo_  <'c:\example.ijs'

26.7 Library Scripts

The J system comes supplied with a useful library of script files containing predefined utility functions. Library script files are organized in a set of directories. The topmost of these library directories is identified by the expression (1!:42 '') which yields a pathname as a string:

   1!:42 ''

Within this topmost library directory, a typical library script-file might be, for example, system\main\dates.ijs. This contains functions for handling calendar dates, and can of course loaded with 0!:0 (although we will see below there is a better way.)

   0!:0 < (1!:42 ''), 'system\main\dates.ijs'

We can inspect one of the utility functions just loaded:

7: | 3: + todayno

26.8 The Profile

A J session begins with the automatic behind-the-scenes loading of a script file called the "profile". The contents of the profile can be whatever we choose - whatever function definitions or other things we find convenient to have on hand as our regular setup at the beginning of a session. Commonly a profile itself loads a further selection of library scripts and our own scripts.

The profile to be used is specified in the operating-system command-line initiating the J session. If no profile is specified in the command-line, then a standard system-supplied profile is used. In this case a session begins with the automatic execution of:

     0!:0 < (1!:42 ''),'system\extras\config\profile.ijs'

Loading this standard profile will load a further standard selection of library scripts, to give a set of commonly useful predefined verbs. The user can customize the standard profile to load further scripts.

26.8.1 load and loadd

Among these useful predefined verbs is load. Its effect is the same as 0!:0, that is, to load a script without displaying a transcript.

   load 'c:\example.ijs'

Notice that the argument filename above can be a plain string, not boxed. A companion verb is loadd, which, like 0!:1 loads a script displaying a transcript.

load and loadd have several advantages over 0!:0 and 0!:1. The first advantage of load is that for a library script the full pathname is not needed: a simple name is enough. Instead of

   load (1!:42 ''), 'system\main\dates.ijs'

it is enough to say

   load 'dates'

To achieve this effect, load and loadd use a predefined catalog of all the library scripts, set up in the course of executing the standard profile. The catalog is a noun - a boxed table - named PUBLIC_j_ . There are many scripts; the first 7 are shown by:

     7 {.  PUBLIC_j_
|colib   |c:\j\system\main\colib.ijs             |z|
|color16 |c:\j\system\packages\color\color16.ijs |z|
|compare |c:\j\system\main\compare.ijs           |z|
|convert |c:\j\system\main\convert.ijs           |z|
|dates   |c:\j\system\main\dates.ijs             |z|
|dd      |c:\j\system\main\dd.ijs                |z|

Each row has a simple name, the associated full path-name for the script, and finally a locale, usually z or j, into which the script will be loaded. PUBLIC_j_ is itself set up from a file system\extras\config\scripts.ijs. This file can be edited by the user. Thus the second advantage of load is that a script can be automatically steered into an appropriate locale on loading.

The third advantage of load is this. Suppose one script depends on (definitions in) a second script. If the first includes a line such as load 'second' then the second is automatically loaded when the first is loaded.

If we load the first script again (say, after correcting an error) then the second will be loaded again. This may be unnecessary or undesirable. To avoid repeated loading of the second script we can require it rather than load it, that is load it only if not already loaded.

Here is a demonstration. Suppose we have these two lines for the first script:

   (0 : 0) (1!:2) < 'c:\first.ijs'
    require 'c:\second.ijs'
    a =: a + 1

Here the variable a is a counter: every time first.ijs is loaded, a will be incremented. Similarly for a second script:

   (0 : 0) (1!:2) < 'c:\second.ijs'
    b  =: b + 1

We set the counters a and b to zero, load the first script and inspect the counters:

(a =: 0),(b =: 0) load 'c:\first.ijs' a,b
0 0
1 1

Evidently each script has executed once. If we now load the first again, we see that it has executed again, but the second has not:

load 'c:\first.ijs' a,b
2 1

The effect is achieved by automatically tracking what has been loaded with load or loadd in a table called LOADED_j_.

|c:\book\tools\mnemonic.ijs| |
|c:\example.ijs            | |
|c:\first.ijs              | |
|c:\second.ijs             | |

The fourth advantage of load is that it respects local assignments (because at the heart of load is 0!: 0).

The fifth advantage of load is that an optional left argument can specify a locale into which to load the script. For example:

   'mylocale' load 'c:\example.ijs'

26.8.2 More on Load Status

We saw above that the J system maintains a record of which scripts have been loaded with the load verb. There is another separate system which keeps track of ALL scripts loaded, whether with load or with 0!:0. The built-in verb 4 !: 3 with a null argument gives a report as a boxed list of filenames.

   ,. 4 !: 3 ''
|c:\book\tools\pr1406.ijs             |
|c:\j\system\extras\util\boot.ijs     |
|c:\j\system\main\stdlib.ijs          |
|c:\j\system\main\winlib.ijs          |
|c:\j\system\main\colib.ijs           |
|c:\j\system\main\loadlib.ijs         |
|c:\j\system\main\jadelib.ijs         |
|c:\j\system\extras\config\winpos.ijs |
|c:\j\system\extras\util\configur.ijs |
|c:\j\system\extras\config\config.ijs |
|c:\book\tools\pr2406.ijs             |
|c:\book\tools\mnemonic.ijs           |
|c:\j\system\main\files.ijs           |
|c:\book\work\current.ijs             |
|c:\example.ijs                       |
|c:\exb.ijs                           |
|c:\exc.ijs                           |
|c:\exd.ijs                           |
|c:\j\system\main\dates.ijs           |
|c:\first.ijs                         |
|c:\second.ijs                        |

We see some scripts loaded by the standard profile, and others particular to this session. Recall that we defined plus in the script example.ijs which we loaded above. The built-in verb 4!:4 keeps track of which name was loaded from which script. The argument is a name (plus for example) and the result is an index into the list of scripts generated by 4!:3. We see that plus was indeed defined by loading the script example.ijs

i =: 4!:4 < 'plus' i { 4!:3 ''

26.8.3 Summary

The recommendation is :

  • Use the standard profile, or the standard profile with additional customizing. This ensures that a session begins having loaded the standard library scripts.
  • Use load, loadd or require for loading scripts.

This is the end of Chapter 26.

Table of Contents

Copyright © Roger Stokes 2002. This material may be freely reproduced, provided that this copyright notice is also reproduced.

last updated 15 Mar 2002